commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r7400 - trunk/gnue-common/src/datasources


From: reinhard
Subject: [gnue] r7400 - trunk/gnue-common/src/datasources
Date: Mon, 18 Apr 2005 12:16:30 -0500 (CDT)

Author: reinhard
Date: 2005-04-18 12:16:29 -0500 (Mon, 18 Apr 2005)
New Revision: 7400

Modified:
   trunk/gnue-common/src/datasources/GDataSource.py
Log:
Added some comments and put functions in a (hopefully) better order.


Modified: trunk/gnue-common/src/datasources/GDataSource.py
===================================================================
--- trunk/gnue-common/src/datasources/GDataSource.py    2005-04-18 15:47:48 UTC 
(rev 7399)
+++ trunk/gnue-common/src/datasources/GDataSource.py    2005-04-18 17:16:29 UTC 
(rev 7400)
@@ -38,14 +38,21 @@
 # <datasource>
 # =============================================================================
 
-class GDataSource(GObjects.GObj):
+class GDataSource (GObjects.GObj):
   """
   Class that handles DataSources.  This is a subclass of GObj, which
   means this class can be created from XML markup and stored in an
   Object tree (e.g., a Forms tree).
   """
-  def __init__(self, parent=None, type="GDataSource"):
-    GObjects.GObj.__init__(self, parent, type)
+
+  # 
--------------------------------------------------------------------------- 
+  # Constructor
+  # 
--------------------------------------------------------------------------- 
+
+  def __init__ (self, parent = None, type = "GDataSource"):
+
+    GObjects.GObj.__init__ (self, parent, type)
+
     self.type = "object"
     self.connection = None
     self._connections = None
@@ -59,7 +66,8 @@
     self._rowidField = None
     self._primarykeyFields = []
 
-    self._inits =[self.primaryInit, self.secondaryInit, self.tertiaryInit]
+    self._inits = [self.__primaryInit, self.__secondaryInit,
+                   self.__tertiaryInit]
     self._currentResultSet = None
     self._resultSetListeners = []
     self._toplevelParent = None # Needs to be set by subclass
@@ -70,42 +78,108 @@
     # The master DataSource object
     self.__master = None
 
-    #
-    # trigger support
-    #
     self._triggerGlobal = True
-    self._triggerFunctions = 
{'createResultSet':{'function':self.createResultSet,
-                                                 },
-                              
'simpleQuery':{'function':self.triggerSimpleQuery,
-                                             },
-                              
'delete':{'function':self.deleteCurrentRecordsetEntry
-                                        },
-                              
'call':{'function':self.callFuncOfCurrentRecordsetEntry
-                                        },
-                              'getCondition':{'function':self.getCondition},
-                              'setCondition':{'function':self.setCondition},
-                              'count' : {'function':self.triggerGetCount},
-                              'update': {'function':
-                                self.updateCurrentRecordSet}
-                              }
 
-    self._triggerProperties = {'extensions':{'get':self.getExtensions,
-                                           'direct':1},
-                                'recordCount':{'get':self.triggerGetCount,
-                                               'direct':1},
-                                'order_by':{'get':self.triggerGetOrderBy,
-                                            'set':self.triggerSetOrderBy,
-                                               'direct':1},
-                               }
+    self._triggerFunctions = {
+        'createResultSet': {'function': self.__trigger_createResultSet},
+        'simpleQuery'    : {'function': self.__trigger_simpleQuery},
+        'update'         : {'function': self.__trigger_update},
+        'delete'         : {'function': self.__trigger_delete},
+        'call'           : {'function': self.__trigger_call},
+        'getCondition'   : {'function': self.getCondition},
+        'setCondition'   : {'function': self.setCondition},
+        'count'          : {'function': self.__trigger_get_recordCount}
+    }
 
+    self._triggerProperties = {
+        'extensions' : {'get'   : self.__trigger_get_extensions,
+                        'direct': 1},
+        'recordCount': {'get'   : self.__trigger_get_recordCount,
+                        'direct': 1},
+        'order_by'   : {'get'   : self.__trigger_get_order_by,
+                        'set'   : self.__trigger_set_order_by,
+                        'direct': 1}
+    }
+
+
+  # ---------------------------------------------------------------------------
+  # Functions and properties available in triggers
+  # ---------------------------------------------------------------------------
+
+  def __trigger_createResultSet (self, conditions = {}, readOnly = False):
+    self.createResultSet (conditions, readOnly)
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_simpleQuery (self, maskDict):
+    conditions = GConditions.buildConditionFromDict (
+        queryDict, GConditions.GClike)
+    resultSet = self.createResultSet (conditions)
+    return [record.getFieldsAsDict () for record in resultSet]
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_update (self):
+
+    self.postAll ()
+    self.requeryAll ()
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_delete (self):
+    (self._currentResultSet.getPostingRecordset ()).delete ()
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_call (self, name, params):
+    self.postAll ()
+    result = self._currentResultSet.current.call (name, params)
+    self.requeryAll ()
+    return result
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_get_extensions (self):
+    return self.extensions
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_get_recordCount (self):
+    if self._currentResultSet:
+      return len (self._currentResultSet)
+    else:
+      return 0
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_get_order_by (self):
+    return self.sorting
+
+  # ---------------------------------------------------------------------------
+
+  def __trigger_set_order_by (self, value):
+    self.sorting = self.__convertOrderBy (value)
+    if self._dataObject:
+      self._dataObject.sorting = self.sorting
+
+
+  # ---------------------------------------------------------------------------
+  # Hack to hide the DataObject behind the DataSource
+  # ---------------------------------------------------------------------------
+
   def __getattr__(self, attr):
     if self._dataObject and attr[1] != '_' and hasattr(self._dataObject,attr):
       return getattr(self._dataObject,attr)
     else:
       raise AttributeError, attr
 
-  def _buildObject(self):
 
+  # ---------------------------------------------------------------------------
+  # Initialize object after parsing from XML
+  # ---------------------------------------------------------------------------
+
+  def _buildObject (self):
+
     # Added 0.5.0 -- Delete before 1.0
     if hasattr(self,'database'):
       self.connection = self.database
@@ -134,141 +208,78 @@
 
     return GObjects.GObj._buildObject(self)
 
-  def triggerGetOrderBy(self):
-    return self.sorting
 
-  def triggerSetOrderBy(self,value):
-    self.sorting = self.__convertOrderBy (value)
-    if self._dataObject:
-      self._dataObject.sorting = self.sorting
+  # ---------------------------------------------------------------------------
+  # Initialize object after parsing from XML
+  # ---------------------------------------------------------------------------
 
-  def triggerGetCount(self):
-    if self._currentResultSet:
-      return len(self._currentResultSet)
-    else:
-      return 0
+  def __primaryInit (self):
 
-  def triggerSimpleQuery(self,maskDict):
-    queryDict = {}
-    okToProcess = True
-    for key in maskDict.keys():
-      queryDict[key] = "%s" % maskDict[key]
-      if not len(queryDict[key]):
-        okToProcess = False
-        break
+    self._topObject = self.findParentOfType(self._toplevelParent)
+    gDebug (9, "Setting %s to connect mgr %s" \
+        % (self.name, self._topObject._connections))
+    self.__getSortOrder ()
+    self.setConnectionManager(self._topObject._connections)
+    self.initialize()
+    self.connect()
+    self.extensions = self._dataObject.triggerExtensions
 
-    conditions = 
GConditions.buildConditionFromDict(queryDict,GConditions.GClike)
-    resultSet = self.createResultSet(conditions)
-    recordCount = resultSet.getRecordCount()
 
-    returnList = []
-    for count in range(recordCount):
-      record = resultSet.getRecord(count)
-      resultDict = {}
-      for key in record.keys():
-        resultDict[key]=record.getField(key) or ""
-      returnList.append(resultDict)
-    return returnList
+  # ---------------------------------------------------------------------------
+  # Initialize object after parsing from XML
+  # ---------------------------------------------------------------------------
 
-  def deleteCurrentRecordsetEntry(self):
-    self._currentResultSet.getPostingRecordset().delete()
+  # TODO: Merged into GDataSource per the TODOs in reports and forms however
+  # TODO: self._topObject._datasourceDictionary implies that the top object
+  # TODO: always has a specifc structure.  This is a bad thing :(  Maybe 
GRootObj
+  # TODO: should contain a getDatasourceDict()?
+  #
+  def __secondaryInit (self):
 
+    if hasattr(self, 'master') and self.master:
 
-  # ---------------------------------------------------------------------------
-  # Sync the current record with the backend
-  # ---------------------------------------------------------------------------
+      self.master = string.lower(self.master)
+      gDebug (7, "Linking detail '%s' to master '%s'" \
+                 % (self.name, self.master))
 
-  def updateCurrentRecordSet (self):
-    """
-    Send changes to the backend and update local data to reflect changes done
-    by the backend.
-    """
+      if self._topObject._datasourceDictionary.has_key(self.master):
+        self.__master = self._topObject._datasourceDictionary [self.master]
+        masterDataObject = self.__master.getDataObject ()
+        detailDataObject = self.getDataObject ()
+        masterDataObject.addDetailDataObject (detailDataObject, self)
+      else:
+        tmsg = u_("Detail source '%(source)s' references non-existant master "
+                  "'%(master)s'") \
+               % {'source': self.name,
+                  'master': self.master}
+        raise StandardError, tmsg
 
-    self.postAll ()
-    self.requeryAll ()
 
-
   # ---------------------------------------------------------------------------
-  # Call a backend function for the current record
+  # Initialize object after parsing from XML
   # ---------------------------------------------------------------------------
 
-  def callFuncOfCurrentRecordsetEntry (self, name, params):
-    """
-    Call function in the backend for the current record.
-    """
+  def __tertiaryInit (self):
 
-    self.postAll ()
-    result = self._currentResultSet.current.call (name, params)
-    self.requeryAll ()
-    return result
+    if hasattr(self, 'prequery'):
+      if not self.hasMaster() and self.prequery:
+        self.createResultSet()
 
 
   # ---------------------------------------------------------------------------
-  # Post all changes in this datasource to the backend
+  # Set the Connection Manager for this DataSource
   # ---------------------------------------------------------------------------
 
-  def postAll (self):
-    """
-    Post all changes to the backend.
+  def setConnectionManager (self, connectionManager):
+    self._connections = connectionManager
 
-    This function posts the top level master datasource of this datasource and
-    all of that datasource's children.
 
-    After calling postAll, L{requeryAll} must be called.
-    """
-
-    if self.__master:
-      self.__master.postAll ()
-    else:
-      self._currentResultSet.post ()
-
-
   # ---------------------------------------------------------------------------
-  # Requery data from the backend
+  # Initialize the datasource
   # ---------------------------------------------------------------------------
 
-  def requeryAll (self):
-    """
-    Requery data from the backend.
+  def initialize(self):
 
-    This must be called after L{postAll} to synchronize the datasource with
-    changes that happened in the backend (through backend triggers). It
-    requeries the top level master datasource of this datasource and all of
-    that datasource's children.
-    """
-
-    if self.__master:
-      self.__master.requeryAll ()
-    else:
-      self._currentResultSet.requery ()
-
-
-  #
-  # get/set the static condition assosiated with a datasource
-  # the static condition is build out of the <condition> child
-  # elements below a datasource XML definition
-  #
-  def setCondition(self, mycondition):
-    self._dataObject._staticCondition = mycondition
-#   dataObject.invalidateCachedConditions()
-
-  def getCondition(self):
-    return self._dataObject._staticCondition
-
-  #
-  # get the dbdriver extension object
-  #
-  def getExtensions(self):
-    return self.extensions
-
-  #
-  # This method should be called after the object is created
-  # but before any other methods are called
-  #
-  def setConnectionManager(self, connectionManager):
-    self._connections = connectionManager
-
-  def initialize(self):
     if not self.connection:
       # We are a connectionless datasource (virtual?)
       # We have to bind to something, so bind to empty or static driver
@@ -356,17 +367,37 @@
     self._dataObject.sorting = self.sorting
 
 
+  # ---------------------------------------------------------------------------
+  # Open a backend connection for this datasource
+  # ---------------------------------------------------------------------------
+
   def connect(self):
     if self.connection != None:
       self._connections.requestConnection(self._dataObject)
 
 
-  def getDataObject(self):
-    return self._dataObject
+  # ---------------------------------------------------------------------------
+  # Set the static condition for this datasource
+  # ---------------------------------------------------------------------------
 
+  def setCondition (self, mycondition):
+    self._dataObject._staticCondition = mycondition
 
-  def referenceField(self, field, defaultValue=None):
 
+  # ---------------------------------------------------------------------------
+  # Return the static condition for this datasource
+  # ---------------------------------------------------------------------------
+
+  def getCondition (self):
+    return self._dataObject._staticCondition
+
+
+  # ---------------------------------------------------------------------------
+  # Reference a bound field
+  # ---------------------------------------------------------------------------
+
+  def referenceField (self, field, defaultValue = None):
+
     if self.type == 'unbound':
       gDebug (1, "Trying to bind field %s to unbound DataSource" % field)
       return
@@ -378,7 +409,12 @@
     if defaultValue != None:
       self._defaultData [field] = defaultValue
 
-  def referenceFields(self, fields):
+
+  # ---------------------------------------------------------------------------
+  # Reference several bound fields
+  # ---------------------------------------------------------------------------
+
+  def referenceFields (self, fields):
     for field in fields:
       if isinstance (field, types.StringType) or \
          isinstance (field, types.UnicodeType):
@@ -386,6 +422,11 @@
       else:
         self.referenceField(*field)
 
+
+  # ---------------------------------------------------------------------------
+  # Reference an unbound field
+  # ---------------------------------------------------------------------------
+
   def referenceUnboundField(self, field, defaultValue=None):
 
     gDebug (7,'Unbound Field %s implicitly referenced' % field)
@@ -395,90 +436,133 @@
       self._defaultData [field] = defaultValue
 
 
-  #
-  # The following is a simple wrapper around the datasource's dataobject
-  # to hide the dataobject from the app programmer
-  #
-  def hasMaster(self):
+  # ---------------------------------------------------------------------------
+  # Register a listener for changes of the ResultSet
+  # ---------------------------------------------------------------------------
+
+  def registerResultSetListener(self, listener):
+    self._resultSetListeners.append(listener)
+
+
+  # ---------------------------------------------------------------------------
+  # Called by dbdrivers whenever this datasource's master has changed
+  # ---------------------------------------------------------------------------
+
+  def masterResultSetChanged(self, masterResultSet, detailResultSet):
+    self._masterResultSet = masterResultSet
+    self.__setResultSet (detailResultSet)
+
+
+  # ---------------------------------------------------------------------------
+  # Get the DataObject instance
+  # ---------------------------------------------------------------------------
+
+  def getDataObject(self):
+    return self._dataObject
+
+
+  # ---------------------------------------------------------------------------
+  # Return True if this datasource is a detail
+  # ---------------------------------------------------------------------------
+
+  def hasMaster (self):
     return self._dataObject != None and self._dataObject.hasMaster()
 
+
+  # ---------------------------------------------------------------------------
+  # Add a detail dataobject for this (master) datasource
+  # ---------------------------------------------------------------------------
+
+  def addDetailDataObject (self, dataObject, handler=None):
+      self._dataObject.addDetailDataObject(dataObject, handler)
+
+
+  # ---------------------------------------------------------------------------
+  # Create a result set
+  # ---------------------------------------------------------------------------
+
   def createResultSet (self, conditions = {}, readOnly = False):
       resultSet = self._dataObject.createResultSet (conditions, readOnly)
       self.__setResultSet (resultSet)
       return resultSet
 
-  def addDetailDataObject(self, dataObject, handler=None):
-      self._dataObject.addDetailDataObject(dataObject, handler)
 
+  # ---------------------------------------------------------------------------
+  # Create an empty result set
+  # ---------------------------------------------------------------------------
+
   def createEmptyResultSet(self, readOnly=False,masterRecordSet=None):
       resultSet = self._dataObject.createEmptyResultSet(readOnly, 
masterRecordSet=masterRecordSet)
-      self.__setResultSet( resultSet )
+      self.__setResultSet (resultSet)
       return resultSet
 
-  #
-  # Master/detail stuff
-  #
 
-  # Called by dbdrivers whenever this datasource's master has changed
-  def masterResultSetChanged(self, masterResultSet, detailResultSet):
-    self._masterResultSet = masterResultSet
-    self.__setResultSet( detailResultSet )
+  # ---------------------------------------------------------------------------
+  # Get the DataObject instance
+  # ---------------------------------------------------------------------------
 
   def __setResultSet(self, resultSet):
     self._currentResultSet = resultSet
     self.notifyResultSetListeners ()
 
+
+  # ---------------------------------------------------------------------------
+  # Find a specific record in the resultset by field values
+  # ---------------------------------------------------------------------------
+
+  def findRecord(self, fieldValues):
+    self._currentResultSet.findRecord(fieldValues)
+
+
+  # ---------------------------------------------------------------------------
+  # Get the DataObject instance
+  # ---------------------------------------------------------------------------
+
   def notifyResultSetListeners (self):
     for listener in self._resultSetListeners:
       listener (self._currentResultSet)
 
-  def registerResultSetListener(self, listener):
-    self._resultSetListeners.append(listener)
 
-  def primaryInit(self):
-    self._topObject = self.findParentOfType(self._toplevelParent)
-    gDebug (9, "Setting %s to connect mgr %s" \
-        % (self.name, self._topObject._connections))
-    self.__getSortOrder ()
-    self.setConnectionManager(self._topObject._connections)
-    self.initialize()
-    self.connect()
-    self.extensions = self._dataObject.triggerExtensions
+  # ---------------------------------------------------------------------------
+  # Post all changes in this datasource to the backend
+  # ---------------------------------------------------------------------------
 
+  def postAll (self):
+    """
+    Post all changes to the backend.
 
-  # TODO: Merged into GDataSource per the TODOs in reports and forms however
-  # TODO: self._topObject._datasourceDictionary implies that the top object
-  # TODO: always has a specifc structure.  This is a bad thing :(  Maybe 
GRootObj
-  # TODO: should contain a getDatasourceDict()?
-  #
-  def secondaryInit(self):
+    This function posts the top level master datasource of this datasource and
+    all of that datasource's children.
 
-    if hasattr(self, 'master') and self.master:
+    After calling postAll, L{requeryAll} must be called.
+    """
 
-      self.master = string.lower(self.master)
-      gDebug (7, "Linking detail '%s' to master '%s'" \
-                 % (self.name, self.master))
+    if self.__master:
+      self.__master.postAll ()
+    else:
+      self._currentResultSet.post ()
 
-      if self._topObject._datasourceDictionary.has_key(self.master):
-        self.__master = self._topObject._datasourceDictionary [self.master]
-        masterDataObject = self.__master.getDataObject ()
-        detailDataObject = self.getDataObject ()
-        masterDataObject.addDetailDataObject (detailDataObject, self)
-      else:
-        tmsg = u_("Detail source '%(source)s' references non-existant master "
-                  "'%(master)s'") \
-               % {'source': self.name,
-                  'master': self.master}
-        raise StandardError, tmsg
 
+  # ---------------------------------------------------------------------------
+  # Requery data from the backend
+  # ---------------------------------------------------------------------------
 
+  def requeryAll (self):
+    """
+    Requery data from the backend.
 
-  def tertiaryInit(self):
-    if hasattr(self, 'prequery'):
-      if not self.hasMaster() and self.prequery:
-        self.createResultSet()
+    This must be called after L{postAll} to synchronize the datasource with
+    changes that happened in the backend (through backend triggers). It
+    requeries the top level master datasource of this datasource and all of
+    that datasource's children.
+    """
 
+    if self.__master:
+      self.__master.requeryAll ()
+    else:
+      self._currentResultSet.requery ()
 
+
   # ---------------------------------------------------------------------------
   # Make sure we have either no sort order, or one in the proper format
   # ---------------------------------------------------------------------------
@@ -560,27 +644,30 @@
     return result
 
 
-
-  # Find a specific record in the resultset by field values
-  def findRecord(self, fieldValues):
-    self._currentResultSet.findRecord(fieldValues)
-
-  #
+  # ---------------------------------------------------------------------------
   # Hooks for record-level triggers
-  #
+  # ---------------------------------------------------------------------------
 
   def _beforeCommitInsert(self, record):
     return 1
 
+  # ---------------------------------------------------------------------------
+
   def _beforeCommitUpdate(self, record):
     return 1
 
+  # ---------------------------------------------------------------------------
+
   def _beforeCommitDelete(self, record):
     return 1
 
+  # ---------------------------------------------------------------------------
+
   def _onModification(self, record):
     return 1
 
+  # ---------------------------------------------------------------------------
+
   def _onRecordLoaded(self, record):
     return 1
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]