commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r7440 - in trunk/gnue-common/src/datasources: . drivers/Base


From: reinhard
Subject: [gnue] r7440 - in trunk/gnue-common/src/datasources: . drivers/Base
Date: Wed, 20 Apr 2005 15:26:19 -0500 (CDT)

Author: reinhard
Date: 2005-04-20 15:26:18 -0500 (Wed, 20 Apr 2005)
New Revision: 7440

Modified:
   trunk/gnue-common/src/datasources/Exceptions.py
   trunk/gnue-common/src/datasources/GDataSource.py
   trunk/gnue-common/src/datasources/drivers/Base/DataObject.py
Log:
Code cleanup.


Modified: trunk/gnue-common/src/datasources/Exceptions.py
===================================================================
--- trunk/gnue-common/src/datasources/Exceptions.py     2005-04-20 16:58:29 UTC 
(rev 7439)
+++ trunk/gnue-common/src/datasources/Exceptions.py     2005-04-20 20:26:18 UTC 
(rev 7440)
@@ -46,6 +46,7 @@
   # does not support (e.g., not all dbdrivers support raw sql mode.)
   pass
 
+
 # -----------------------------------------------------------------------------
 # Read only violation
 # -----------------------------------------------------------------------------
@@ -88,15 +89,64 @@
 
 
 # -----------------------------------------------------------------------------
-# 
+# Invalid <datasource> definitions
 # -----------------------------------------------------------------------------
 
-class MasterDetailFieldMismatch(errors.ApplicationError):
-  # Raised when a the number of master fields doesn't match the
-  # number of detail fields. (e.g., masterlink="id,subid"
-  # and detaillink="id" would be a problem; must be 1:1)
+class InvalidDatasourceDefinition (errors.ApplicationError):
+  """
+  <datasource> definition is incomplete or self-contradictory.
+  """
   pass
 
+# -----------------------------------------------------------------------------
+
+class MasterNotFoundError (InvalidDatasourceDefinition):
+  """
+  "master" attribute points to an non-existant datasource.
+  """
+  def __init__ (self, name, master):
+    InvalidDatasourceDefinition.__init__ (self,
+        u_("Detail datasource '%(name)s' references non-existant master "
+           "'%(master)s'") % {'name': name, 'master': master})
+
+# -----------------------------------------------------------------------------
+
+class MissingMasterlinkError (InvalidDatasourceDefinition):
+  """
+  "masterlink" attribute missing.
+  """
+  def __init__ (self, name):
+    InvalidDatasourceDefinition.__init__ (self,
+        u_("Datasource '%s' contains a 'master' attribute, but no 'masterlink' 
"
+           "attribute") % name)
+
+# -----------------------------------------------------------------------------
+
+class MissingDetaillinkError (InvalidDatasourceDefinition):
+  """
+  "detaillink" attribute missing.
+  """
+  def __init__ (self, name):
+    InvalidDatasourceDefinition.__init__ (self,
+        u_("Datasource '%s' contains a 'master' attribute, but no 'detaillink' 
"
+           "attribute") % name)
+
+# -----------------------------------------------------------------------------
+
+class MasterDetailFieldMismatch (InvalidDatasourceDefinition):
+  """
+  "masterfield" and "detailfield" attributes contain different numbers of
+  fields
+  """
+  def __init__ (self, name):
+    InvalidDatasourceDefinition.__init__ (self,
+        u_("Number of fields in 'masterlink' and 'detaillink' attributes does "
+           "not match for datasource '%s'") % name)
+
+# -----------------------------------------------------------------------------
+#
+# -----------------------------------------------------------------------------
+
 class ConnectionError(errors.AdminError):
   # Generic error reading from the database connection
   pass
@@ -110,10 +160,3 @@
   # Raised when a database adapter doesn't support
   # writing Schema to datasource
   pass
-
-class InvalidDatasourceDefintion(errors.ApplicationError):
-  # Raised when a <datasource> definition is
-  # incomplete or otherwise doesn't make sense
-  # (e.g., a <datasource type="sql"> without a
-  # <sql> section.
-  pass

Modified: trunk/gnue-common/src/datasources/GDataSource.py
===================================================================
--- trunk/gnue-common/src/datasources/GDataSource.py    2005-04-20 16:58:29 UTC 
(rev 7439)
+++ trunk/gnue-common/src/datasources/GDataSource.py    2005-04-20 20:26:18 UTC 
(rev 7440)
@@ -58,6 +58,9 @@
     self._connections = None
     self._connection = None             # GConnection object
     self._dataObject = None
+    self.__master = None                # Master DataSource object
+    self._masterPkFields = []           # M/D link fields in the master table
+    self._masterFkFields = []           # M/D link fields in the detail table
     self._fieldReferences = {}
     self._defaultData = {}
     self._rowidField = None
@@ -72,9 +75,6 @@
     self._topObject = None
     self.sorting = None
 
-    # The master DataSource object
-    self.__master = None
-
     self._triggerGlobal = True
 
     self._triggerFunctions = {
@@ -207,7 +207,7 @@
 
 
   # ---------------------------------------------------------------------------
-  # Initialize object after parsing from XML
+  # Phase 1 init: Find connection object and open connection
   # ---------------------------------------------------------------------------
 
   def __primaryInit (self):
@@ -222,37 +222,50 @@
 
 
   # ---------------------------------------------------------------------------
-  # Initialize object after parsing from XML
+  # Phase 2 init: Link with master
   # ---------------------------------------------------------------------------
 
   # 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()?
+  # TODO: always has a specifc structure.  This is a bad thing :(  Maybe
+  # TODO: GRootObj should contain a getDatasourceDict()?
   #
   def __secondaryInit (self):
 
-    if hasattr(self, 'master') and self.master:
+    # Master/Detail handling
+    # FIXME: Could this be merged with primary init, and done before connect?
+    # So bugs in the datasource definition would be reported before asking for
+    # connection login.
+    if hasattr (self, 'master'):
 
-      self.master = string.lower(self.master)
-      gDebug (7, "Linking detail '%s' to master '%s'" \
-                 % (self.name, self.master))
+      # Find the master datasource by name
+      self.__master = self._topObject._datasourceDictionary.get (
+          self.master.lower ())
 
-      if self._topObject._datasourceDictionary.has_key(self.master):
-        self.__master = self._topObject._datasourceDictionary [self.master]
-        masterDataObject = self.__master._dataObject
-        detailDataObject = self._dataObject
-        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
+      if self.__master is None:
+        raise Exceptions.MasterNotFoundError (self.name, self.master)
 
+      # Get the primary key fields from the "masterlink" attribute
+      if not hasattr (self, 'masterlink'):
+        raise Exceptions.MissingMasterlinkError (self.name)
+      self._masterPkFields = [s.strip () for s in self.masterlink.split (',')]
 
+      # Get the foreign key fields from the "detaillink" attribute
+      if not hasattr (self, 'detaillink'):
+        raise Exceptions.MissingDetaillinkError (self.name)
+      self._masterFkFields = [s.strip () for s in self.detaillink.split (',')]
+
+      # Check if the number of fields matches
+      if len (self._masterPkFields) != len (self._masterFkFields):
+        raise Exceptions.MasterDetailFieldMismatch (self.name)
+
+      masterDataObject = self.__master._dataObject
+      detailDataObject = self._dataObject
+      masterDataObject.addDetailDataObject (detailDataObject, self)
+
+
   # ---------------------------------------------------------------------------
-  # Initialize object after parsing from XML
+  # Phase 3 init: do prequery
   # ---------------------------------------------------------------------------
 
   def __tertiaryInit (self):

Modified: trunk/gnue-common/src/datasources/drivers/Base/DataObject.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/DataObject.py        
2005-04-20 16:58:29 UTC (rev 7439)
+++ trunk/gnue-common/src/datasources/drivers/Base/DataObject.py        
2005-04-20 20:26:18 UTC (rev 7440)
@@ -43,9 +43,6 @@
     self._connection = connection
     self.__dataSource = dataSource
 
-    self.masterlink = ""
-    self.detaillink = ""
-
     self._masterfields = []
     self._detailfields = []
     self._staticCondition = None
@@ -128,10 +125,6 @@
         hasattr (dataObject, 'detaillink') and \
           dataObject.detaillink or "", ',')
 
-    if len(dataObject._masterfields) != len(dataObject._detailfields):
-      tmsg = u_("master=%s; detail=%s") % (dataObject._masterfields, 
dataObject._detailfields)
-      raise Exceptions.MasterDetailFieldMismatch, tmsg
-
     # Make sure "master" fields will be in our future query
     for field in dataObject._masterfields:
       self.__dataSource._fieldReferences[string.strip(field)] = ""





reply via email to

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