/[gnue]/gnue-common/src/datasources/GConnections.py
ViewVC logotype

Diff of /gnue-common/src/datasources/GConnections.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.52 by jamest, Mon Mar 10 16:45:24 2003 UTC revision 1.53 by jcater, Tue Nov 25 17:01:28 2003 UTC
# Line 33  Line 33 
33  from ConfigParser import *  from ConfigParser import *
34  import sys, string, copy, netrc  import sys, string, copy, netrc
35  from gnue.common.apps import GDebug  from gnue.common.apps import GDebug
36  from gnue.common.datasources import GDataObjects  from gnue.common.datasources import Exceptions
37  from gnue.common.datasources import GLoginHandler  from gnue.common.datasources import GLoginHandler
38  from gnue.common.datasources.drivers import DRIVERS as ALLDRIVERS  from gnue.common.datasources.drivers import DRIVERS as ALLDRIVERS
39  from gnue.common.utils.FileUtils import openResource, dyn_import  from gnue.common.utils.FileUtils import openResource, dyn_import
# Line 56  class InvalidFormatError (Error): Line 56  class InvalidFormatError (Error):
56    # in an unreadable format.    # in an unreadable format.
57    pass    pass
58    
59  LoginError = GDataObjects.LoginError  LoginError = Exceptions.LoginError
60    
61    
62  class GConnections:  class GConnections:
# Line 182  class GConnections: Line 182  class GConnections:
182      self._definitions[string.lower(name)] = copy.copy(parameters)      self._definitions[string.lower(name)] = copy.copy(parameters)
183    
184    
185    
186      def getConnection(self, connection_name, login=0):
187    
188    
189        connection_name = connection_name.lower()
190    
191        try:
192          return self._openConnections[connection_name]
193        except KeyError:
194          pass
195    
196        # Support for multiple open connections
197        # to same database.
198        # Specify as 'gnue:1', 'gnue:2', etc, to open
199        # two actual connections to 'gnue', each with
200        # their own transactions, etc.
201        connection_base = connection_name.split(':')[0]
202    
203        # This will throw a GConnections.NotFoundError if an unknown
204        # connection name is specified.  The calling method should
205        # catch this exception and handle it properly (exit w/message)
206    
207        parameters = self.getConnectionParameters(connection_base)
208    
209        driver = parameters['provider'].lower().replace('/','.')
210        behavior = parameters.get('behavior','').lower().replace('/','.')
211    
212        try:
213          basedriver, extradriver =driver.split('.',1)
214          extradriver = "." + extradriver
215        except:
216          basedriver = driver
217          extradriver = ""
218    
219        path = []
220    
221        dbdriver = None
222    
223        basemodule = _find_base_driver(basedriver, ALLDRIVERS)
224        GDebug.printMesg(1,'Using %s as base driver for %s' %  (basemodule, driver))
225    
226        if basemodule:
227          dbdriver = _get_dbdriver(basemodule + extradriver)
228    
229        if not dbdriver:
230          tmsg = _("No database driver found for provider type '%s'") % driver
231          raise Exceptions.ProviderNotSupportedError, tmsg
232    
233    
234        conn = dbdriver.Connection(self, connection_name, parameters)
235        self._openConnections[connection_name] = conn
236    
237        if login:
238          self.loginToConnection(conn)
239    
240        # TODO: Process the behavior = and
241        # TODO: set conn.behavior= to the
242        # TODO: specific Introspection class
243        return conn
244    
245    
246    #    #
247    # Return a database provider object    # Return a database provider object
248    #    #
249    def getDataObject(self, connection_name, connection_type):    def getDataObject(self, connection_name, connection_type):
250    
251      # This will throw a GConnections.NotFoundError if an unknown      # This will throw a GConnections.NotFoundError if an unknown
252      # connection name is specified.  The calling method should      # connection name is specified.  The calling method should
253      # catch this exception and handle it properly (exit w/message)      # catch this exception and handle it properly (exit w/message)
254      return _load_dbdriver(      connection = self.getConnection(connection_name)
255         self.getConnectionParameters(connection_name),  
256         connection_type, self)      try:
257          dd = connection.supportedDataObjects[connection_type](connection)
258          GDebug.printMesg (1,'Attaching to %s (%s)' % (dd.__class__.__name__, connection_type))
259          return dd
260        except KeyError:
261          tmsg = _("DB Driver '%s' does not support source type '%s'") % (connection, connection_type)
262          raise Exceptions.ObjectTypeNotAvailableError, tmsg
263    
264    
265    
266    #    #
267    # Has a connection been initialized/established?    # Has a connection been initialized/established?
268    #    #
269      # TODO: this was likely broken
270    def isConnectionActive(self, connection):    def isConnectionActive(self, connection):
271      return self._openConnections.has_key(string.lower(connection))      return self._openConnections.has_key(string.lower(connection))
272    
# Line 204  class GConnections: Line 274  class GConnections:
274    #    #
275    # Get a data connection for a specified database    # Get a data connection for a specified database
276    #    #
277    def requestConnection(self, dataObject, connection):    def requestConnection(self, dataObject):
278      connection_name = string.lower(connection)  
279      if self._openConnections.has_key(connection_name):      print """TODO: once this branch makes it into CVS head,
280          eliminate the GConnections.requestConnection logic!"""
281        # If a database connetion has already been established, use it  
282        dataObject.setDataConnection(self._openConnections[connection_name])      # Support for multiple open connections
283        GDebug.printMesg(5,'Reusing data connection to %s' % connection_name)      # to same database.
284        # Specify as 'gnue:1', 'gnue:2', etc, to open
285        # two actual connections to 'gnue', each with
286        # their own transactions, etc.
287    
288        self.loginToConnection(dataObject._connection)
289        dataObject.connect()
290    
     else:  
291    
292        # Get the parameters from the Connections Definition File    def loginToConnection(self, connection):
       loginData = self.getConnectionParameters(connection_name)  
293    
294        connection_name = connection.name
295        connection_base = connection_name.split(':')[0]
296    
297        try:
298          connected = connection.__connected
299        except AttributeError:
300          connected = 0
301    
302        if not connected:
303          loginData = connection.parameters
304        try:        try:
305          # load the user's netrc file:          # load the user's netrc file:
306          # a sample .netrc could look like:          # a sample .netrc could look like:
# Line 229  class GConnections: Line 313  class GConnections:
313          #  set the HOME environement variable [SET HOME=...])          #  set the HOME environement variable [SET HOME=...])
314    
315          netrcData = netrc.netrc().authenticators(          netrcData = netrc.netrc().authenticators(
316                "'gnue://%s/'" % connection_name )                "'gnue://%s/'" % connection_base )
317          if netrcData!=None:          if netrcData!=None:
318            GDebug.printMesg(5, 'Read the user\'s .netrc file')            GDebug.printMesg(5, 'Read the user\'s .netrc file')
319            loginData['_username'] = netrcData[0][1:-1]            loginData['_username'] = netrcData[0][1:-1]
# Line 249  class GConnections: Line 333  class GConnections:
333        # Load        # Load
334        if loginData.has_key('custom_auth'):        if loginData.has_key('custom_auth'):
335          authenticator = dyn_import(loginData['custom_auth']).Authenticator()          authenticator = dyn_import(loginData['custom_auth']).Authenticator()
336          checkFields = authenticator.getLoginFields(dataObject.getLoginFields())          checkFields = authenticator.getLoginFields(connection.getLoginFields())
337        else:        else:
338          checkFields = dataObject.getLoginFields()          checkFields = connection.getLoginFields()
339          authenticator = None          authenticator = None
340    
341        haveAllInformation = 1        haveAllInformation = 1
# Line 261  class GConnections: Line 345  class GConnections:
345            break            break
346    
347        if haveAllInformation:        if haveAllInformation:
348          try:  #        try:
349            self._authenticatedUsers[connection] = loginData['_username']  #          self._authenticatedUsers[base] = loginData['_username']
350          except KeyError:  #        except KeyError:
351            self._authenticatedUsers[connection] = None  #          self._authenticatedUsers[base] = None
352    
353          if authenticator:          if authenticator:
354            dataObject.connect(authenticator.login(loginData))            connection.connect(authenticator.login(loginData))
355          else:          else:
356            dataObject.connect(loginData)            connection.connect(loginData)
         GDebug.printMesg(5, 'I had enough information to connect to %s without asking the user' % connection_name)  
         # Save the newly opened connection for future datasources  
         self._openConnections[connection_name] = dataObject.getDataConnection()  
357    
358        else:        else:
359          attempts = 4          attempts = 4
# Line 286  class GConnections: Line 367  class GConnections:
367    
368              # Ask the UI to prompt for our login data              # Ask the UI to prompt for our login data
369              loginData.update(self._loginHandler.getLogin(              loginData.update(self._loginHandler.getLogin(
370                [connection_name,                [connection_base,
371                 self.getConnectionParameter(connection_name,'comment',''),                 self.getConnectionParameter(connection_base,'comment',''),
372                 checkFields], errortext))                 checkFields], errortext))
373    
374              # Add to authenticated user list              # Add to authenticated user list
# Line 298  class GConnections: Line 379  class GConnections:
379    
380              # Ask the data object to connect to the database              # Ask the data object to connect to the database
381              if authenticator:              if authenticator:
382                dataObject.connect(authenticator.login(loginData))                connection.connect(authenticator.login(loginData))
383              else:              else:
384                dataObject.connect(loginData)                connection.connect(loginData)
   
             # Save the newly opened connection for future datasources  
             self._openConnections[connection_name] = \  
                 dataObject.getDataConnection()  
385    
386              # We're done!              # We're done!
387              attempts = 0              attempts = 0
388              self._loginHandler.destroyLoginDialog()              self._loginHandler.destroyLoginDialog()
389    
390            except GDataObjects.LoginError, error:            except Exceptions.LoginError, error:
391              # Oops, they must have entered an invalid user/password.              # Oops, they must have entered an invalid user/password.
392              # Those silly users.              # Those silly users.
393              # user: Hey! Who are you calling silly?!!!              # user: Hey! Who are you calling silly?!!!
394                # Ok, then "those d@mn users"
395              attempts = attempts - 1              attempts = attempts - 1
396              errortext = string.replace("%s" % error,'\n','')              errortext = string.replace("%s" % error,'\n','')
397              self._loginHandler.destroyLoginDialog()              self._loginHandler.destroyLoginDialog()
# Line 322  class GConnections: Line 400  class GConnections:
400                # Four times is plenty...                # Four times is plenty...
401                #self._loginHandler.destroyLoginDialog()                #self._loginHandler.destroyLoginDialog()
402                tmsg = _("Unable to log in after 4 attempts.\n\nError: %s") % error                tmsg = _("Unable to log in after 4 attempts.\n\nError: %s") % error
403                raise GDataObjects.LoginError, tmsg                raise Exceptions.LoginError, tmsg
404    
405            except GLoginHandler.UserCanceledLogin:            except GLoginHandler.UserCanceledLogin:
406              # Guess they changed their minds. Treat as a login error.              # Guess they changed their minds. Treat as a login error.
407              self._loginHandler.destroyLoginDialog()              self._loginHandler.destroyLoginDialog()
408              tmsg = _("User canceled the login request.")              tmsg = _("User canceled the login request.")
409              raise GDataObjects.LoginError, tmsg              raise Exceptions.LoginError, tmsg
410    
411        # Create the introspection instance
412        try:
413          behavior = connection.behavior
414        except AttributeError:
415          behavior = connection.defaultBehavior
416        connection.introspector = behavior(connection)
417    
418        # Done
419        connection.__connected = 1
420    
421    
422    def getAuthenticatedUser(self, connection=None):    def getAuthenticatedUser(self, connection=None):
423      try:      try:
# Line 344  class GConnections: Line 433  class GConnections:
433  #  #
434  # Load the correct DBdriver from gnue/common/datasources/drivers/*/  # Load the correct DBdriver from gnue/common/datasources/drivers/*/
435  #  #
 def _load_dbdriver(parameters, type, connectionManager):  
   
   
   driver = parameters['provider'].lower().replace('/','.')  
   behavior = parameters.get('behavior','').lower().replace('/','.')  
   
   d = driver.split('.')  
   basedriver = d[0]  
   if len(d) > 1:  
     extradriver = "." + string.join(d[1:],'.')  
   else:  
     extradriver = ""  
   
   path = []  
   
   dbdriver = None  
   
   basemodule = _find_base_driver(basedriver, ALLDRIVERS)  
   GDebug.printMesg(1,'Using %s as base driver for %s' %  (basemodule, driver))  
   
   if basemodule:  
     dbdriver = _get_dbdriver(basemodule + extradriver)  
   
   if not dbdriver:  
     tmsg = _("No database driver found for provider type '%s'") % driver  
     raise GDataObjects.ProviderNotSupportedError, tmsg  
   
   try:  
     dd = dbdriver.supportedDataObjects[type]()  
     GDebug.printMesg (1,'Attaching to %s (%s)' % (driver,dd.__class__.__name__))  
     return dd  
   except KeyError:  
     tmsg = _("DB Driver '%s' does not support source type '%s'") % (driver, type)  
     raise GDataObjects.ObjectTypeNotAvailableError, tmsg  
   
436    
437  def _find_base_driver (driver, modules, path=[]):  def _find_base_driver (driver, modules, path=[]):
438    if driver in modules:    if driver in modules:
439      return 'gnue.common.datasources.drivers.' + string.join(path + [driver],'.')      return 'gnue.common.datasources.drivers.' + string.join(path + [driver],'.')
440    else:    else:
441      for module in modules:      for module in modules:
442          print "trying module: %s" % module
443        try:        try:
444          m = dyn_import ('gnue.common.datasources.drivers.' + string.join(path + [module],'.')).DRIVERS          m = dyn_import ('gnue.common.datasources.drivers.' + string.join(path + [module],'.')).DRIVERS
445          rs = _find_base_driver(driver, m, path + [module])          rs = _find_base_driver(driver, m, path + [module])
# Line 393  def _find_base_driver (driver, modules, Line 448  def _find_base_driver (driver, modules,
448        except (AttributeError, ImportError), err:        except (AttributeError, ImportError), err:
449          pass          pass
450          ##print "Not in " + 'gnue.common.datasources.drivers.' + string.join(path + [module],'.')          ##print "Not in " + 'gnue.common.datasources.drivers.' + string.join(path + [module],'.')
451          except AdapterNotInstalled:
452            GDebug.printMesg(1,'%s does not have all dependencies installed' % driver)
453    
454    
455  def _get_dbdriver (driver):  def _get_dbdriver (driver):
456    dbdriver = None    dbdriver = None
457    
458    try:    try:
459      dbdriver = dyn_import("%s.Driver" % (driver))      dbdriver = dyn_import("%s" % (driver))
460        dbdriver.Connection
461    except:    except:
462      GDebug.printMesg(1,'%s is not a dbdriver' % ( driver))      GDebug.printMesg(1,'%s is not a dbdriver' % ( driver))
463      try:      try:
# Line 410  def _get_dbdriver (driver): Line 468  def _get_dbdriver (driver):
468            return dbdriver            return dbdriver
469      except (ImportError, AttributeError):      except (ImportError, AttributeError):
470        GDebug.printMesg(1,'%s does not contain dbdrivers' % (driver))        GDebug.printMesg(1,'%s does not contain dbdrivers' % (driver))
471        except AdapterNotInstalled:
472          GDebug.printMesg(1,'%s does not have all dependencies installed' % driver)
473    
474    return dbdriver    return dbdriver
475    

Legend:
Removed from v.1.52  
changed lines
  Added in v.1.53

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26