commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r7297 - trunk/gnue-common/src/datasources/drivers/Base


From: reinhard
Subject: [gnue] r7297 - trunk/gnue-common/src/datasources/drivers/Base
Date: Mon, 4 Apr 2005 18:13:31 -0500 (CDT)

Author: reinhard
Date: 2005-04-04 18:13:30 -0500 (Mon, 04 Apr 2005)
New Revision: 7297

Modified:
   trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
Log:
Added some comments, changed function order to a more logical one.


Modified: trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2005-04-04 
22:33:32 UTC (rev 7296)
+++ trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2005-04-04 
23:13:30 UTC (rev 7297)
@@ -23,21 +23,26 @@
 
 __all__ = ['ResultSet']
 
-from gnue.common.datasources import GConditions, Exceptions
 import string
 
+from gnue.common.datasources import Exceptions
+
 from RecordSet import RecordSet
 
-###########################################################
-#
-#
-#
-###########################################################
+# =============================================================================
+# Basic ResultSet class
+# =============================================================================
+
 class ResultSet:
 
   _recordSetClass = RecordSet
 
-  def __init__(self, dataObject, 
cursor=None,defaultValues={},masterRecordSet=None):
+  # ---------------------------------------------------------------------------
+  # Constructor
+  # ---------------------------------------------------------------------------
+
+  def __init__ (self, dataObject, cursor = None, defaultValues = {},
+                masterRecordSet = None):
      self._dataObject = dataObject
      self._cursor = cursor
      self._cachedRecords = []
@@ -66,65 +71,160 @@
      if masterRecordSet:
        masterRecordSet.addDetailResultSet(self)
 
-  # Since we are overriding __len__
-  def __nonzero__(self):
-    return 1
 
-  # Return the # of records
-  def __len__(self):
-    return self.getRecordCount()
+  # ---------------------------------------------------------------------------
+  # Status information
+  # ---------------------------------------------------------------------------
 
-  def __getitem__(self, index):
-    rs = self.getRecord(index)
-    if not rs:
-      raise IndexError
-    else:
-      return rs
-
-
-  # Returns whether this result set is read only or not
-  def isReadOnly(self):
+  def isReadOnly (self):
     return self._readonly
 
+  # ---------------------------------------------------------------------------
 
-  # Returns 1=At first record, 0=Not first record
-  def isFirstRecord(self):
+  def isFirstRecord (self):
     return (self._currentRecord == 0)
 
+  # ---------------------------------------------------------------------------
 
-  # Returns 1=At last record, 0=Not last record
-  def isLastRecord(self):
+  def isLastRecord (self):
     if self._currentRecord < len(self._cachedRecords) - 1 or \
        self._cacheNextRecord():
       return False
     else:
       return True
 
+  # ---------------------------------------------------------------------------
 
   # returns -1=No records in memory, #=Current record #
-  def getRecordNumber(self):
+  def getRecordNumber (self):
     return self._currentRecord
 
+  # ---------------------------------------------------------------------------
 
-  # returns # of records currently loaded
-  def getCacheCount(self):
-    return len(self._cachedRecords)
+  def getCacheCount (self):
+    return len (self._cachedRecords)
 
-  # returns # of records the
-  def getRecordCount(self):
+  # ---------------------------------------------------------------------------
+
+  def getRecordCount (self):
     return self._recordCount > 0 and self._recordCount or self.getCacheCount()
 
+  # ---------------------------------------------------------------------------
+
+  # Returns True if the resultset or a detail resultset has uncommitted changes
+  def isPending(self):
+    for rec in (self._cachedRecords):
+      if rec.isPending ():
+        return True
+    return False
+
+  # ---------------------------------------------------------------------------
+
+  # Returns 1=DataObject has uncommitted changes
+  def isRecordPending(self):
+    return self.current.isPending()
+
+  # ---------------------------------------------------------------------------
+
+  # Returns 1=Field is bound to a database field
+  # TODO: pass a list of bound field names to RecordSet instead
+  def isFieldBound(self, fieldName):
+
+    # TODO: until the case problem get's fixed in common we do the following
+    # workaround.
+    for item in self._dataObject._fieldReferences.keys ():
+      if item.lower () == fieldName.lower ():
+        return True
+
+    return False
+
+
+  # ---------------------------------------------------------------------------
+  # Load cacheCount number of new records
+  # ---------------------------------------------------------------------------
+
+  def _cacheNextRecord (self):
+    rs = self._loadNextRecord()
+    if rs:
+      self._dataObject._dataSource._onRecordLoaded(self._cachedRecords[-1])
+    return rs
+
+
+  # ---------------------------------------------------------------------------
   # Get a specific record (0=based)
-  def getRecord(self, record):
-    while (record + 1 > len(self._cachedRecords)) and self._cacheNextRecord():
+  # ---------------------------------------------------------------------------
+
+  def getRecord (self, record):
+    while (record + 1 > len (self._cachedRecords)) and self._cacheNextRecord 
():
       pass
 
-    if record + 1 > len(self._cachedRecords):
+    if record + 1 > len (self._cachedRecords):
       return None
     else:
-      return self._cachedRecords[record]
+      return self._cachedRecords [record]
 
 
+  # ---------------------------------------------------------------------------
+  # Get data as array
+  # ---------------------------------------------------------------------------
+
+  def getArray (self, fields):
+    """
+    This function returns the values of the given fields for all records as a
+    2-dimensional list. The record pointer is *not* moved.
+    """
+
+    # First, load all records into the cache
+    while self._cacheNextRecord():
+      pass
+
+    # Now build up the array
+    result = []
+    for record in self._cachedRecords:
+      line = []
+      for field in fields:
+        line.append (record [field])
+      result.append (line)
+    return result
+
+
+  # ---------------------------------------------------------------------------
+  # Notification of record navigation
+  # ---------------------------------------------------------------------------
+
+  # TODO: Unify __notifyListeners and notifyDetailObjects
+
+  # Other objects can register here. Their currentRecordMoved method will then
+  # get called whenever the current record of this ResultSet changes.
+  def registerListener (self, listener):
+    if listener not in self.__listeners:
+      self.__listeners.append (listener)
+    # Inform new listener about current record. This happens whenever the
+    # *Resultset* (not the current record but the whole resultset) changes.
+    if self._currentRecord >= 0:
+      listener.currentRecordMoved ()
+
+  # ---------------------------------------------------------------------------
+
+  # This gets called whenever the ResultSet gets a new current recordset,
+  # that happens in case of record navigation, in case of inserting a new
+  # record, and in case of posting data (the current record could have been
+  # deleted, or the backend could have changed some data).
+  def __notifyListeners (self):
+    for listener in self.__listeners:
+      listener.currentRecordMoved ()
+
+  # ---------------------------------------------------------------------------
+
+  def notifyDetailObjects(self):
+    gDebug (8,'Master record changed; Notifying Detail Objects')
+    for detail in self._dataObject._detailObjects:
+      if detail[1]:
+        detail[1].masterResultSetChanged(self,
+                                         detail[0]._masterRecordChanged(self))
+
+  # ---------------------------------------------------------------------------
+
   # Sync self.current with self._currentRecord and adjust detail resultsets and
   # the user interface
   def __sync (self):
@@ -136,6 +236,11 @@
     self.__notifyListeners ()
 
 
+  # ---------------------------------------------------------------------------
+  # Record navigation
+  # ---------------------------------------------------------------------------
+
+
   # Move to a record number already in cache
   # -1 sets the current record to None
   def __move (self, record):
@@ -145,50 +250,46 @@
       self._currentRecord = record
       self.__sync ()
 
+  # ---------------------------------------------------------------------------
 
-  # move to record #, returns record or None if record number out of range
-  def setRecord(self, record):
-
+  def setRecord (self, record):
     while (record > len(self._cachedRecords) -1) and self._cacheNextRecord():
       pass
-
     if record >= len(self._cachedRecords):
       return None
     else:
       self.__move (record)
       return self.current
 
+  # ---------------------------------------------------------------------------
 
-  # returns next record, or None if no more records
-  def nextRecord(self):
-    if self._currentRecord + 1 == len(self._cachedRecords):
-      if not self._cacheNextRecord():
+  def nextRecord (self):
+    if self._currentRecord + 1 == len (self._cachedRecords):
+      if not self._cacheNextRecord ():
         return None
-
     self.__move (self._currentRecord + 1)
     return self.current
 
+  # ---------------------------------------------------------------------------
 
-  # returns 1=New record loaded, 0=At first record
-  def prevRecord(self):
+  def prevRecord (self):
     if self._currentRecord < 1:
       return None
     else:
       self.__move (self._currentRecord - 1)
       return self.current
 
+  # ---------------------------------------------------------------------------
 
-  # returns 1=at first record, 0=No records loaded
-  def firstRecord(self):
+  def firstRecord (self):
     if self._currentRecord < 0:
       if not self._cacheNextRecord():
         return None
-
     self.__move (0)
     return self.current
 
+  # ---------------------------------------------------------------------------
 
-  # returns 1=at last record, 0=No records loaded
   def lastRecord(self):
     if self._currentRecord == -1:
       return None
@@ -199,43 +300,6 @@
       return self.current
 
 
-
-  # Insert a blank record after the current record
-  def insertRecord(self):
-    if self.isReadOnly():
-      # Provide better feedback??
-      tmsg =  _("Attempted to insert into a read only datasource")
-      raise Exceptions.ReadOnlyError, tmsg
-    else:
-      gDebug (8, 'Inserting a blank record in %s' % self)
-      self._currentRecord += 1
-      self._cachedRecords.insert(self._currentRecord, 
self._createEmptyRecord())
-      self._recordCount += 1
-      self.current = self._cachedRecords[self._currentRecord]
-
-      # Set any dataobject-wide default values
-      for field in self._dataObject._defaultValues.keys():
-        gDebug (8, "DataObject-Wide default for %s" % field)
-        self.current.setField(field, 
self._dataObject._defaultValues[field],False)
-
-      # Set any resultset specific values
-      for field in self._defaultValues.keys():
-        gDebug (8, "ResultSet-specific default for %s" % field)
-        self.current.setField(field, self._defaultValues[field],False)
-
-      # Pull any primary keys from a master record set
-      if self._masterRecordSet != None and hasattr(self._dataObject, 
'_masterfields'):
-        i = 0
-        for field in self._dataObject._masterfields:
-          gDebug (8, "Value for %s to %s" % (field, \
-                     self._masterRecordSet.getField (field)))
-          
self.current.setField(self._dataObject._detailfields[i],self._masterRecordSet.getField(field),False)
-          i += 1
-
-      self.notifyDetailObjects()
-      self.__notifyListeners ()
-      return self.current
-
   # ---------------------------------------------------------------------------
   # Find a record by field values
   # ---------------------------------------------------------------------------
@@ -268,50 +332,51 @@
     self.__move (-1)
     return self.current
 
+
   # ---------------------------------------------------------------------------
-  # Get data as array
+  # Insert a new record after the current one
   # ---------------------------------------------------------------------------
 
-  def getArray (self, fields):
-    """
-    This function returns the values of the given fields for all records as a
-    2-dimensional list. The record pointer is *not* moved.
-    """
+  def insertRecord(self):
+    if self.isReadOnly():
+      # Provide better feedback??
+      tmsg =  _("Attempted to insert into a read only datasource")
+      raise Exceptions.ReadOnlyError, tmsg
+    else:
+      gDebug (8, 'Inserting a blank record in %s' % self)
+      self._currentRecord += 1
+      self._cachedRecords.insert(self._currentRecord, 
self._createEmptyRecord())
+      self._recordCount += 1
+      self.current = self._cachedRecords[self._currentRecord]
 
-    # First, load all records into the cache
-    while self._cacheNextRecord():
-      pass
+      # Set any dataobject-wide default values
+      for field in self._dataObject._defaultValues.keys():
+        gDebug (8, "DataObject-Wide default for %s" % field)
+        self.current.setField(field, 
self._dataObject._defaultValues[field],False)
 
-    # Now build up the array
-    result = []
-    for record in self._cachedRecords:
-      line = []
-      for field in fields:
-        line.append (record [field])
-      result.append (line)
-    return result
+      # Set any resultset specific values
+      for field in self._defaultValues.keys():
+        gDebug (8, "ResultSet-specific default for %s" % field)
+        self.current.setField(field, self._defaultValues[field],False)
 
-  # ---------------------------------------------------------------------------
-  # Close the result set
-  # ---------------------------------------------------------------------------
+      # Pull any primary keys from a master record set
+      if self._masterRecordSet != None and hasattr(self._dataObject, 
'_masterfields'):
+        i = 0
+        for field in self._dataObject._masterfields:
+          gDebug (8, "Value for %s to %s" % (field, \
+                     self._masterRecordSet.getField (field)))
+          
self.current.setField(self._dataObject._detailfields[i],self._masterRecordSet.getField(field),False)
+          i += 1
 
-  def close (self):
-    """
-    This function should be called, if a result set is no longer needed. It
-    breaks up reference cycles so garbage collection can do it's job.
-    """
+      self.notifyDetailObjects()
+      self.__notifyListeners ()
+      return self.current
 
-    for item in self._cachedRecords:
-      item._parent = None
 
-    if self._dataObject._dataSource:
-      self._dataObject._dataSource.close ()
+  # ---------------------------------------------------------------------------
+  # Create a new record with a copy of the existing one
+  # ---------------------------------------------------------------------------
 
-    self._dataObject    = None
-    self._cachedRecords = []
-    self.__listeners    = []
-
-
   def duplicateRecord(self, exclude=(), include=()):
     current = self.current
     inserted = self.insertRecord()
@@ -346,19 +411,11 @@
 
     return inserted
 
-  # Returns 1=DataObject, or a detail resultset, has uncommitted changes
-  def isPending(self):
-    for rec in (self._cachedRecords):
-      if rec.isPending ():
-        return True
-    return False
 
+  # ---------------------------------------------------------------------------
+  # TODO: What's this??
+  # ---------------------------------------------------------------------------
 
-  # Returns 1=DataObject has uncommitted changes
-  def isRecordPending(self):
-    return self.current.isPending()
-
-
   def getPostingRecordset(self):
     global postingRecordset
     return postingRecordset
@@ -421,6 +478,7 @@
       else:
         self._currentRecord = -1
 
+
   # ---------------------------------------------------------------------------
   # Sync resultset with backend, and sync listeners with resultset
   # ---------------------------------------------------------------------------
@@ -441,121 +499,85 @@
     self.__sync ()
 
 
-  def notifyDetailObjects(self):
-    gDebug (8,'Master record changed; Notifying Detail Objects')
-    for detail in self._dataObject._detailObjects:
-      if detail[1]:
-        detail[1].masterResultSetChanged(self,
-                                         detail[0]._masterRecordChanged(self))
+  # ---------------------------------------------------------------------------
+  # Close the result set
+  # ---------------------------------------------------------------------------
 
+  def close (self):
+    """
+    This function should be called, if a result set is no longer needed. It
+    breaks up reference cycles so garbage collection can do it's job.
+    """
 
-  # Other objects can register here. Their currentRecordMoved method will then
-  # get called whenever the current record of this ResultSet changes.
-  def registerListener (self, listener):
-    if listener not in self.__listeners:
-      self.__listeners.append (listener)
-    # Inform new listener about current record. This happens whenever the
-    # *Resultset* (not the current record but the whole resultset) changes.
-    if self._currentRecord >= 0:
-      listener.currentRecordMoved ()
+    for item in self._cachedRecords:
+      item._parent = None
 
+    if self._dataObject._dataSource:
+      self._dataObject._dataSource.close ()
 
-  # This gets called whenever the ResultSet gets a new current recordset,
-  # that happens in case of record navigation, in case of inserting a new
-  # record, and in case of posting data (the current record could have been
-  # deleted, or the backend could have changed some data).
-  def __notifyListeners (self):
-    for listener in self.__listeners:
-      listener.currentRecordMoved ()
+    self._dataObject    = None
+    self._cachedRecords = []
+    self.__listeners    = []
 
 
-  # Returns 1=Field is bound to a database field
-  def isFieldBound(self, fieldName):
-
-    # TODO: until the case problem get's fixed in common we do the following
-    # workaround.
-    for item in self._dataObject._fieldReferences.keys ():
-      if item.lower () == fieldName.lower ():
-        return True
-
-    return False
-
-
-  # Load cacheCount number of new records
-  def _cacheNextRecord(self):
-    rs = self._loadNextRecord()
-    if rs:
-      self._dataObject._dataSource._onRecordLoaded(self._cachedRecords[-1])
-    return rs
-
-
   # ---------------------------------------------------------------------------
-  # Nice string representation
+  # Virtual methods
   # ---------------------------------------------------------------------------
 
-  def __repr__ (self):
-    do = self._dataObject
-    if hasattr (do, 'table'):
-      return "<ResultSet for %s>" % do.table
-    else:
-      return "<Unbound/Static ResultSet>"
-
-
-  ###
-  ### Methods below should be overridden by Vendor Specific functions
-  ### (_createEmptyRecord may not need to be overridden in all cases)
-  ###
-
   # Load cacheCount number of new records
   def _loadNextRecord(self):
     return False
 
+  # ---------------------------------------------------------------------------
+
   # Create an empty recordset
   def _createEmptyRecord (self):
     return self._recordSetClass (parent = self,
         rowidField = self.__rowidField,
         primarykeyFields = self.__primarykeyFields)
 
-  # Iterator support (Python 2.2+)
-  def __iter__(self):
-    return _ResultSetIter(self)
 
+  # ---------------------------------------------------------------------------
+  # Sequence behaviour
+  # ---------------------------------------------------------------------------
 
+  def __iter__ (self):
+    record = self.firstRecord ()
+    while record:
+      yield record
+      record = self.nextRecord ()
 
-# A simple resultset iterator
-# Lets you use ResultSets as:
-#
-#   for record in myResultSet:
-#      blah
-#
-# NOTE: Python 2.2+  (but it won't get called in
-#    Python 2.1 or below, so not a problem)
-#
-class _ResultSetIter:
-  def __init__(self, resultset):
-    self.resultset = resultset
-    self.used = False
-    self.done = False
+  # ---------------------------------------------------------------------------
 
-  def __iter__(self):
-    return self
+  def __nonzero__ (self):
+    return True
 
-  def next(self):
-    if self.done:
-      raise StopIteration
-    if not self.used:
-      rs = self.resultset.firstRecord()
-      self.used = True
+  # ---------------------------------------------------------------------------
+
+  def __len__ (self):
+    return self.getRecordCount ()
+
+  # ---------------------------------------------------------------------------
+
+  def __getitem__ (self, index):
+    record = self.getRecord (index)
+    if not record:
+      raise IndexError
     else:
-      rs = self.resultset.nextRecord()
+      return record
 
-    if not rs:
-      self.done = True
-      raise StopIteration
+
+  # ---------------------------------------------------------------------------
+  # Nice string representation
+  # ---------------------------------------------------------------------------
+
+  def __repr__ (self):
+    do = self._dataObject
+    if hasattr (do, 'table'):
+      return "<ResultSet for %s>" % do.table
     else:
-      return rs
+      return "<Unbound/Static ResultSet>"
 
 
 # TODO: wtf?
 postingRecordset = None
-





reply via email to

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