commit-gnue
[Top][All Lists]
Advanced

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

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


From: reinhard
Subject: [gnue] r8399 - trunk/gnue-common/src/datasources/drivers/Base
Date: Wed, 12 Apr 2006 14:12:00 -0500 (CDT)

Author: reinhard
Date: 2006-04-12 14:11:58 -0500 (Wed, 12 Apr 2006)
New Revision: 8399

Modified:
   trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
Log:
Updated coding standard, added new method _refresh() to get new data from the
backend.


Modified: trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2006-04-11 
13:30:18 UTC (rev 8398)
+++ trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2006-04-12 
19:11:58 UTC (rev 8399)
@@ -37,902 +37,980 @@
 # =============================================================================
 
 class ResultSet:
-  """
-  Representation of a database resultset (a set of records usually representing
-  the result of a database query).
+    """
+    Representation of a database resultset (a set of records usually
+    representing the result of a database query).
 
-  A ResultSet instance encapsulates an ordered set of database records. It
-  maintains a cursor that can be moved around. It also provides functions to
-  insert new records and to post changes to the backend.
+    A ResultSet instance encapsulates an ordered set of database records. It
+    maintains a cursor that can be moved around. It also provides functions to
+    insert new records and to post changes to the backend.
 
-  This class must be subclassed by all database drivers, and a driver must at
-  least implement one of the following functions:
-    - _query_object_ (for normal queries)
-    - _query_sql_ (for raw SQL queries)
-  and the L{_count_}, L{_fetch_} and L{_close_} functions.
-  """
+    This class must be subclassed by all database drivers, and a driver must at
+    least implement one of the following functions:
+        - _query_object_ (for normal queries)
+        - _query_sql_ (for raw SQL queries)
+    and the L{_count_}, L{_fetch_} and L{_close_} functions.
+    """
 
-  # ---------------------------------------------------------------------------
-  # Constructor
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Constructor
+    # -------------------------------------------------------------------------
 
-  def __init__ (self,
-      defaultData      = {},
-      connection       = None,
-      tablename        = None,
-      rowidField       = None,
-      primarykeyFields = [],
-      primarykeySeq    = None,
-      boundFields      = [],
-      requery          = True,
-      readonly         = False,
-      details          = {},
-      eventController  = None):
-    """
-    Create a new ResultSet instance.
+    def __init__(self,
+            defaultData      = {},
+            connection       = None,
+            tablename        = None,
+            rowidField       = None,
+            primarykeyFields = [],
+            primarykeySeq    = None,
+            boundFields      = [],
+            requery          = True,
+            readonly         = False,
+            details          = {},
+            eventController  = None):
+        """
+        Create a new ResultSet instance.
 
-    @param defaultData: Dictionary with default data to be used whenever a new
-      record is inserted in this ResultSet.
-    @param connection: GConnection object the ResultSet object can use to query
-      data and post changes.
-    @param tablename: Table name.
-    @param rowidField: Field name of the field containing a unique row id
-      generated by the backend, if available.
-    @param primarykeyFields: List of field names that make up a unique key, if
-      available.
-    @param primarykeySeq: If this is set to the name of a backend sequence,
-      the getSequence method of the Connection object is called to fill the
-      primarykeyField before posting to the backend.  If primarykeySeq is
-      given, the primarykeyFields may only contain a single field name.
-    @param boundFields: List of fields to be included when posting changes to
-      the backend. All fields not in this list are considered unbound fields
-      and are not persistent.
-    @param requery: If this is set to True, the ResultSet reqeries its values
-      from the backend after posting, in case a backend trigger has changed
-      something. This happens in the L{requery} method which has to be called
-      after L{post}.
-    @param readonly: True if the ResultSet is read only. If set, an attempt to
-      insert, modify or delete any record in this RecordSet raises an
-      exception.
-    @param details: Dictionary defining all details of this ResultSet, where
-      the key is the L{GDataSource} object and the values are tuples
-      containing a list of primary key fields and a list of the corresponding
-      foreign key fields.
-    @param eventController: EventController instance to notify of data events.
-    """
+        @param defaultData: Dictionary with default data to be used whenever a
+            new record is inserted in this ResultSet.
+        @param connection: GConnection object the ResultSet object can use to
+            query data and post changes.
+        @param tablename: Table name.
+        @param rowidField: Field name of the field containing a unique row id
+            generated by the backend, if available.
+        @param primarykeyFields: List of field names that make up a unique key,
+            if available.
+        @param primarykeySeq: If this is set to the name of a backend sequence,
+            the getSequence method of the Connection object is called to fill
+            the primarykeyField before posting to the backend.  If
+            primarykeySeq is given, the primarykeyFields may only contain a
+            single field name.
+        @param boundFields: List of fields to be included when posting changes
+            to the backend. All fields not in this list are considered unbound
+            fields and are not persistent.
+        @param requery: If this is set to True, the ResultSet reqeries its
+            values from the backend after posting, in case a backend trigger
+            has changed something.  This happens in the L{requery} method which
+            has to be called after L{post}.
+        @param readonly: True if the ResultSet is read only. If set, an attempt
+            to insert, modify or delete any record in this RecordSet raises an
+            exception.
+        @param details: Dictionary defining all details of this ResultSet,
+            where the key is the L{GDataSource} object and the values are
+            tuples containing a list of primary key fields and a list of the
+            corresponding foreign key fields.
+        @param eventController: EventController instance to notify of data
+            events.
+        """
 
-    self.__defaultData      = defaultData
-    self.__connection       = connection
-    self.__tablename        = tablename
-    self.__rowidField       = rowidField
-    self.__primarykeyFields = primarykeyFields
-    self.__primarykeySeq    = primarykeySeq
-    self.__boundFields      = boundFields
-    self.__requery          = requery
-    self.__readonly         = readonly
-    self.__details          = details
-    self.__eventController  = eventController
+        self.__defaultData      = defaultData
+        self.__connection       = connection
+        self.__tablename        = tablename
+        self.__rowidField       = rowidField
+        self.__primarykeyFields = primarykeyFields
+        self.__primarykeySeq    = primarykeySeq
+        self.__boundFields      = boundFields
+        self.__requery          = requery
+        self.__readonly         = readonly
+        self.__details          = details
+        self.__eventController  = eventController
 
-    # Data for static datasources
-    self.__staticData = []
+        # Data for static datasources
+        self.__static_data = []
 
-    # List of all RecordSet objects cached in this ResultSet
-    self.__cachedRecords = []
+        # Parameters of last query
+        self.__lastquery_type = None
+        self.__lastquery_cache = None
+        self.__lastquery_kwargs = None
 
-    # Index of the current record
-    self.__currentRecord = -1
+        # Generator to yield fieldname/value dictionaries
+        self.__generator = None
 
-    # Number of records
-    self.__recordCount = 0
+        # List of all RecordSet objects cached in this ResultSet
+        self.__cached_records = []
 
-    # Generator to yield fieldname/value dictionaries
-    self.__generator = None
+        # Index of the current record
+        self.__current_index = -1
 
-    # Pointer to the current record
-    self.current = None
+        # Number of records
+        self.__record_count = 0
 
+        # Pointer to the current record
+        self.current = None
 
-  # ---------------------------------------------------------------------------
-  # Sequence behaviour
-  # ---------------------------------------------------------------------------
 
-  def __iter__ (self):
-    """
-    Return an iterator yielding the records in the resultset as
-    L{RecordSet.RecordSet} instances.
+    # -------------------------------------------------------------------------
+    # Sequence behaviour
+    # -------------------------------------------------------------------------
+
+    def __iter__(self):
+        """
+        Return an iterator yielding the records in the resultset as
+        L{RecordSet.RecordSet} instances.
     
-    The cursor is not moved while iterating through the resultset.
-    """
-    position = 0
-    while True:
-      if position >= len (self.__cachedRecords):
-        if not self.__cacheNextRecord ():
-          break
-      yield self.__cachedRecords [position]
-      position += 1
+        The cursor is not moved while iterating through the resultset.
+        """
+        position = 0
+        while True:
+            if position >= len(self.__cached_records):
+                if not self.__cache_next_record():
+                    break
+            yield self.__cached_records[position]
+            position += 1
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def __nonzero__ (self):
-    return True
+    def __nonzero__(self):
+        return True
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def __len__ (self):
-    return self.getRecordCount ()
+    def __len__(self):
+        return self.getRecordCount()
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def __getitem__ (self, index):
-    record = self.getRecord (index)
-    if not record:
-      raise IndexError
-    else:
-      return record
+    def __getitem__(self, index):
+        record = self.getRecord(index)
+        if not record:
+            raise IndexError
+        else:
+            return record
 
 
-  # ---------------------------------------------------------------------------
-  # String representation
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # String representation
+    # -------------------------------------------------------------------------
 
-  def __repr__ (self):
-    """
-    Shows a string representation of the RecordSet.
-    """
+    def __repr__(self):
+        """
+        Shows a string representation of the RecordSet.
+        """
 
-    if self.__tablename:
-      return "<ResultSet for %s at %d>" % (self.__tablename, id (self))
-    else:
-      return "<Unbound/Static ResultSet at %d>" % id (self)
+        if self.__tablename:
+            return "<ResultSet for %s at %d>" % (self.__tablename, id(self))
+        else:
+            return "<Unbound/Static ResultSet at %d>" % id(self)
 
 
-  # ---------------------------------------------------------------------------
-  # Execute a query
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Execute a query
+    # -------------------------------------------------------------------------
 
-  def query (self, type, cache, **kwargs):
-    """
-    Populate the resultset with data.
+    def query(self, type, cache, **kwargs):
+        """
+        Populate the resultset with data.
 
-    @param type: Type of the query, can be 'object' or 'sql'.
-    @param cache: Size of the cache to use for this query.
-    @param kwargs: Depends on the type.
-    @raise Exceptions.ObjectTypeNotAvailableError: if the requested type of
-      query is not available for this connection.
-    @raise Exception: if the query cannot be executed. The exact exception type
-      depends on the backend.
-    """
+        @param type: Type of the query, can be 'object' or 'sql'.
+        @param cache: Size of the cache to use for this query.
+        @param kwargs: Depends on the type.
+        @raise Exceptions.ObjectTypeNotAvailableError: if the requested type of
+            query is not available for this connection.
+        @raise Exception: if the query cannot be executed. The exact exception
+            type depends on the backend.
+        """
 
-    checktype (type, str)
-    checktype (cache, int)
+        checktype(type, str)
+        checktype(cache, int)
 
-    queryfunc = '_query_' + type + '_'
-    if not hasattr (self, queryfunc):
-      raise Exceptions.ObjectTypeNotAvailableError, type
+        # Dispose current result set data
+        self.__generator = None
+        self.__cached_records = []
+        self.__current_index = -1
+        self.__record_count = 0
+        self.current = None
 
-    getattr (self, queryfunc) (self.__connection, **kwargs)
+        # Remember this query to be able to repeat it in _refresh()
+        self.__lastquery_type = type
+        self.__lastquery_cache = cache
+        self.__lastquery_kwargs = kwargs
 
-    self.__generator = self._fetch_ (cache)
+        queryfunc = '_query_' + type + '_'
+        if not hasattr(self, queryfunc):
+            raise Exceptions.ObjectTypeNotAvailableError, type
 
-    # (TODO: could be delayed to first call of getRecordCount)
-    self.__recordCount = self._count_ ()
+        getattr(self, queryfunc)(self.__connection, **kwargs)
 
+        self.__generator = self._fetch_(cache)
 
-  # ---------------------------------------------------------------------------
-  # Get the number of records in the recordset
-  # ---------------------------------------------------------------------------
+        # (TODO: could be delayed to first call of getRecordCount)
+        self.__record_count = self._count_()
 
-  def getRecordCount (self):
-    """
-    Return the number of records currently in the recordset.
-    """
 
-    if self.__recordCount > 0:
-      return self.__recordCount
-    else:
-      return len (self.__cachedRecords) # Fallback in case record count unknown
+    # -------------------------------------------------------------------------
+    # Get the number of records in the recordset
+    # -------------------------------------------------------------------------
 
+    def getRecordCount(self):
+        """
+        Return the number of records currently in the recordset.
+        """
 
-  # ---------------------------------------------------------------------------
-  # Get a specific record (0=based)
-  # ---------------------------------------------------------------------------
+        if self.__record_count > 0:
+            return self.__record_count
+        else:
+            # Fallback in case record count unknown
+            return len(self.__cached_records)
 
-  def getRecord (self, record):
-    """
-    Return the record at the given position without moving the cursor.
 
-    @param record: the zero-based position of the record to return.
-    @return: the L{RecordSet.RecordSet} instance, or None if the given position
-      is higher than the number of records in the ResultSet.
-    @raise Exception: if the requested record is not yet in cache and fetching
-      it from the backend fails. The exact exception class depends on the
-      backend.
-    """
+    # -------------------------------------------------------------------------
+    # Get a specific record (0=based)
+    # -------------------------------------------------------------------------
 
-    checktype (record, int)
+    def getRecord(self, record):
+        """
+        Return the record at the given position without moving the cursor.
 
-    while (record + 1 > len (self.__cachedRecords)) \
-        and self.__cacheNextRecord ():
-      pass
+        @param record: the zero-based position of the record to return.
+        @return: the L{RecordSet.RecordSet} instance, or None if the given
+            position is higher than the number of records in the ResultSet.
+        @raise Exception: if the requested record is not yet in cache and
+            fetching it from the backend fails. The exact exception class
+            depends on the backend.
+        """
 
-    if record + 1 > len (self.__cachedRecords):
-      return None
-    else:
-      return self.__cachedRecords [record]
+        checktype(record, int)
 
+        while (record + 1 > len(self.__cached_records)) \
+                and self.__cache_next_record():
+            pass
 
-  # ---------------------------------------------------------------------------
-  # Get data as array
-  # ---------------------------------------------------------------------------
+        if record + 1 > len(self.__cached_records):
+            return None
+        else:
+            return self.__cached_records[record]
 
-  def getArray (self, fields):
-    """
-    Return the values of the given fields for all records in the resultset as
-    a 2-dimensional list.
+
+    # -------------------------------------------------------------------------
+    # Get data as array
+    # -------------------------------------------------------------------------
+
+    def getArray(self, fields):
+        """
+        Return the values of the given fields for all records in the resultset
+        as a 2-dimensional list.
     
-    The record pointer is not moved.
+        The record pointer is not moved.
 
-    @param fields: Fieldnames of the fields to include in the array.
-    @raise Exception: if a record is not yet in cache and fetching it from the
-      backend fails. The exact exception class depends on the backend.
-    """
+        @param fields: Fieldnames of the fields to include in the array.
+        @raise Exception: if a record is not yet in cache and fetching it from
+            the backend fails. The exact exception class depends on the
+            backend.
+        """
 
-    checktype (fields, list)
+        checktype(fields, list)
 
-    # First, load all records into the cache
-    while self.__cacheNextRecord ():
-      pass
+        # First, load all records into the cache
+        while self.__cache_next_record():
+            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
+        # Now build up the array
+        result = []
+        for record in self.__cached_records:
+            line = []
+            for field in fields:
+                line.append(record[field])
+            result.append(line)
+        return result
 
 
-  # ---------------------------------------------------------------------------
-  # Get data as multi dimensional dictionary
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Get data as multi dimensional dictionary
+    # -------------------------------------------------------------------------
 
-  def getDictArray (self, keyfields, fields):
-    """
-    Return the values of the given fields for all records as a
-    multidimensional dictionary.
+    def getDictArray(self, keyfields, fields):
+        """
+        Return the values of the given fields for all records as a
+        multidimensional dictionary.
     
-    The record pointer is not moved.
+        The record pointer is not moved.
 
-    @param keyfields: Fieldnames of the fields to use as dictionary keys.
-    @param fields: Fieldnames of the fields to include in the value
-      dictionaries.
-    @return: Dictionary with the values of the first keyfield as key, and the
-      values are dictionaries with the value of the second keyfield as key,
-      and so on, until the last dictionary contains the fieldname/value pairs
-      for the fields given in the second parameter.
-    @raise Exception: if a record is not yet in cache and fetching it from the
-      backend fails. The exact exception class depends on the backend.
-    """
+        @param keyfields: Fieldnames of the fields to use as dictionary keys.
+        @param fields: Fieldnames of the fields to include in the value
+            dictionaries.
+        @return: Dictionary with the values of the first keyfield as key, and
+            the values are dictionaries with the value of the second keyfield
+            as key, and so on, until the last dictionary contains the
+            fieldname/value pairs for the fields given in the second parameter.
+        @raise Exception: if a record is not yet in cache and fetching it from
+            the backend fails. The exact exception class depends on the
+            backend.
+        """
 
-    checktype (keyfields, list)
-    checktype (fields, list)
+        checktype(keyfields, list)
+        checktype(fields, list)
 
-    # First, load all records into the cache
-    while self.__cacheNextRecord ():
-      pass
+        # First, load all records into the cache
+        while self.__cache_next_record():
+            pass
 
-    # Now build up the array
-    result = {}
-    for record in self.__cachedRecords:
-      d = result
-      for field in keyfields:
-        d = d.setdefault (record [field], {})
-      for field in fields:
-        d [field] = record [field]
-    return result
+        # Now build up the array
+        result = {}
+        for record in self.__cached_records:
+            d = result
+            for field in keyfields:
+                d = d.setdefault(record[field], {})
+            for field in fields:
+                d[field] = record[field]
+        return result
 
 
-  # ---------------------------------------------------------------------------
-  # Record navigation
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Record navigation
+    # -------------------------------------------------------------------------
 
-  def firstRecord (self):
-    """
-    Move the cursor to the first record.
+    def firstRecord(self):
+        """
+        Move the cursor to the first record.
 
-    @return: the new current record as a L{RecordSet.RecordSet} instance, or
-      None if the resultset is empty.
-    @raise Exception: if the requested record is not yet in cache and fetching
-      it from the backend fails. The exact exception class depends on the
-      backend.
-    """
-    if self.__currentRecord < 0:
-      if not self.__cacheNextRecord ():
-        return None
-    self.__move (0)
-    return self.current
+        @return: the new current record as a L{RecordSet.RecordSet} instance,
+            or None if the resultset is empty.
+        @raise Exception: if the requested record is not yet in cache and
+            fetching it from the backend fails. The exact exception class
+            depends on the backend.
+        """
+        if self.__current_index < 0:
+            if not self.__cache_next_record():
+                return None
+        self.__move(0)
+        return self.current
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def prevRecord (self):
-    """
-    Move the cursor backwards by one record.
+    def prevRecord(self):
+        """
+        Move the cursor backwards by one record.
 
-    If the cursor already points to the first record, it is not moved.
+        If the cursor already points to the first record, it is not moved.
 
-    @return: the new current record as a L{RecordSet.RecordSet} instance, or
-      None if the cursor already pointed to the first record.
-    """
-    if self.__currentRecord < 1:
-      return None
-    else:
-      self.__move (self.__currentRecord - 1)
-      return self.current
+        @return: the new current record as a L{RecordSet.RecordSet} instance,
+            or None if the cursor already pointed to the first record.
+        """
+        if self.__current_index < 1:
+            return None
+        else:
+            self.__move(self.__current_index - 1)
+            return self.current
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def nextRecord (self):
-    """
-    Move the cursor forward by one record.
+    def nextRecord(self):
+        """
+        Move the cursor forward by one record.
 
-    If the cursor already points to the last record, it is not moved.
+        If the cursor already points to the last record, it is not moved.
 
-    @return: the new current record as a L{RecordSet.RecordSet} instance, or
-      None if the cursor already pointed to the last record.
-    @raise Exception: if the requested record is not yet in cache and fetching
-      it from the backend fails. The exact exception class depends on the
-      backend.
-    """
-    if self.__currentRecord + 1 == len (self.__cachedRecords):
-      if not self.__cacheNextRecord ():
-        return None
-    self.__move (self.__currentRecord + 1)
-    return self.current
+        @return: the new current record as a L{RecordSet.RecordSet} instance,
+            or None if the cursor already pointed to the last record.
+        @raise Exception: if the requested record is not yet in cache and
+            fetching it from the backend fails. The exact exception class
+            depends on the backend.
+        """
+        if self.__current_index + 1 == len(self.__cached_records):
+            if not self.__cache_next_record():
+                return None
+        self.__move(self.__current_index + 1)
+        return self.current
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def lastRecord (self):
-    """
-    Move the cursor to the last record.
+    def lastRecord(self):
+        """
+        Move the cursor to the last record.
 
-    @return: the new current record as a L{RecordSet.RecordSet} instance, or
-      None if the resultset is empty.
-    @raise Exception: if the requested record is not yet in cache and fetching
-      it from the backend fails. The exact exception class depends on the
-      backend.
-    """
-    while self.__cacheNextRecord ():
-      pass
-    if len (self.__cachedRecords) == 0:
-      return None
-    else:
-      self.__move (len (self.__cachedRecords) - 1)
-      return self.current
+        @return: the new current record as a L{RecordSet.RecordSet} instance,
+            or None if the resultset is empty.
+        @raise Exception: if the requested record is not yet in cache and
+            fetching it from the backend fails. The exact exception class
+            depends on the backend.
+        """
+        while self.__cache_next_record():
+            pass
+        if len(self.__cached_records) == 0:
+            return None
+        else:
+            self.__move(len(self.__cached_records) - 1)
+            return self.current
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def setRecord (self, record):
-    """
-    Set the cursor to a specific record.
+    def setRecord(self, record):
+        """
+        Set the cursor to a specific record.
 
-    If the number of the record to set the cursor to is greater than the number
-    of records in the resultset, the cursor is not moved.
+        If the number of the record to set the cursor to is greater than the
+        number of records in the resultset, the cursor is not moved.
 
-    @param record: zero-based number of the record to set the cursor to.
-    @return: the new current record as a L{RecordSet.RecordSet} instance, or
-      None if the record number to set the cursor to is greater than the number
-      of records in the resultset.
-    @raise Exception: if the requested record is not yet in cache and fetching
-      it from the backend fails. The exact exception class depends on the
-      backend.
-    """
-    checktype (record, int)
-    while (record > len (self.__cachedRecords) - 1) \
-        and self.__cacheNextRecord ():
-      pass
-    if record >= len (self.__cachedRecords):
-      return None
-    else:
-      self.__move (record)
-      return self.current
+        @param record: zero-based number of the record to set the cursor to.
+        @return: the new current record as a L{RecordSet.RecordSet} instance,
+            or None if the record number to set the cursor to is greater than
+            the number of records in the resultset.
+        @raise Exception: if the requested record is not yet in cache and
+            fetching it from the backend fails. The exact exception class
+            depends on the backend.
+        """
+        checktype(record, int)
 
-  # ---------------------------------------------------------------------------
+        while (record > len(self.__cached_records) - 1) \
+                and self.__cache_next_record():
+            pass
+        if record >= len(self.__cached_records):
+            return None
+        else:
+            self.__move(record)
+            return self.current
 
-  def findRecord (self, fieldValues):
-    """
-    Find a record by field values.
+    # -------------------------------------------------------------------------
 
-    This function searches through the already loaded records and moves the
-    cursor to the first record to match the given fieldValues dictionary.
-    If no match is found, then the record pointer is set to -1.
+    def findRecord(self, fieldValues):
+        """
+        Find a record by field values.
 
-    @param fieldValues: fieldname/value dictionary to search for.
-    @return: the first record that matches as a L{RecordSet.RecordSet} instance
-      or None if no match was found.
-    @raise Exception: if a record is not already in cache and fetching it from
-      the backend fails. The exact exception class depends on the backend.
-    """
-    checktype (fieldValues, dict)
-    i = 0
-    while True:
-      if i >= len (self.__cachedRecords):
-        if not self.__cacheNextRecord ():
-          # No match found
-          self.__move (-1)
-          return None
-      record = self.__cachedRecords [i]
-      found = True
-      for (key, value) in fieldValues.items ():
-        if record [key] != value:
-          found = False
-          continue
-      if found:
-        self.__move (i)
-        return self.current
-      i += 1
+        This function searches through the already loaded records and moves the
+        cursor to the first record to match the given fieldValues dictionary.
+        If no match is found, then the record pointer is set to -1.
 
-  # ---------------------------------------------------------------------------
+        @param fieldValues: fieldname/value dictionary to search for.
+        @return: the first record that matches as a L{RecordSet.RecordSet}
+            instance or None if no match was found.
+        @raise Exception: if a record is not already in cache and fetching it
+            from the backend fails. The exact exception class depends on the
+            backend.
+        """
+        checktype(fieldValues, dict)
 
-  def __move (self, record):
-    if record != self.__currentRecord \
-         or (self.__currentRecord >= 0 \
-             and self.current != self.__cachedRecords [self.__currentRecord]):
-      self.__currentRecord = record
-      self.__sync ()
+        i = 0
+        while True:
+            if i >= len(self.__cached_records):
+                if not self.__cache_next_record():
+                    # No match found
+                    self.__move(-1)
+                    return None
+            record = self.__cached_records[i]
+            found = True
+            for (key, value) in fieldValues.items():
+                if record[key] != value:
+                    found = False
+                    continue
+            if found:
+                self.__move(i)
+                return self.current
+            i += 1
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def isFirstRecord (self):
-    """
-    Return True if the cursor is at the first record.
-    """
-    return (self.__currentRecord == 0)
+    def __move(self, record):
+        if record != self.__current_index or (self.__current_index >= 0 \
+                and self.current != 
self.__cached_records[self.__current_index]):
+            self.__current_index = record
+            self.__sync()
 
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
 
-  def isLastRecord (self):
-    """
-    Return True if the cursor is at the last record.
+    def isFirstRecord(self):
+        """
+        Return True if the cursor is at the first record.
+        """
+        return (self.__current_index == 0)
 
-    @raise Exception: if the next record is not yet in cache and fetching it
-      from the backend fails. The exact exception class depends on the backend.
-    """
-    if self.__currentRecord < len (self.__cachedRecords) - 1 or \
-       self.__cacheNextRecord ():
-      return False
-    else:
-      return True
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
+    def isLastRecord(self):
+        """
+        Return True if the cursor is at the last record.
 
-  def getRecordNumber (self):
-    """
-    Return the zero-based position of the cursor within the recordset.
-    """
-    return self.__currentRecord
+        @raise Exception: if the next record is not yet in cache and fetching
+            it from the backend fails. The exact exception class depends on the
+            backend.
+        """
+        if self.__current_index < len(self.__cached_records) - 1 or \
+                self.__cache_next_record():
+            return False
+        else:
+            return True
 
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Insert a new record after the current one
-  # ---------------------------------------------------------------------------
+    def getRecordNumber(self):
+        """
+        Return the zero-based position of the cursor within the recordset.
+        """
+        return self.__current_index
 
-  def insertRecord (self, defaultData = {}):
-    """
-    Insert a new, empty record after the current cursor position.
 
-    The cursor is moved to the newly inserted record.
+    # -------------------------------------------------------------------------
+    # Insert a new record after the current one
+    # -------------------------------------------------------------------------
 
-    @param defaultData: fieldname/value pairs to initialize the record with.
-      All fields not given in this dictionary are initialized with None.
-    @return: the newly inserted record.
-    @raise L{Exceptions.ReadOnlyInsertError}: if the ResultSet is read only.
-    """
+    def insertRecord(self, defaultData = {}):
+        """
+        Insert a new, empty record after the current cursor position.
 
-    checktype (defaultData, dict)
+        The cursor is moved to the newly inserted record.
 
-    if self.__readonly:
-      raise Exceptions.ReadOnlyInsertError
+        @param defaultData: fieldname/value pairs to initialize the record
+            with.  All fields not given in this dictionary are initialized with
+            None.
+        @return: the newly inserted record.
+        @raise L{Exceptions.ReadOnlyInsertError}: if the ResultSet is read
+            only.
+        """
 
-    assert gDebug (8, 'Inserting a blank record in %s' % self)
+        checktype(defaultData, dict)
 
-    self.__recordCount += 1
-    self.__currentRecord += 1
-    record = self.__createRecord (defaultData = defaultData,
-                                  position    = self.__currentRecord)
-    self.__sync ()
-    return record
+        if self.__readonly:
+            raise Exceptions.ReadOnlyInsertError
 
+        assert gDebug(8, 'Inserting a blank record in %s' % self)
 
-  # ---------------------------------------------------------------------------
-  # Create a new record with a copy of the existing one
-  # ---------------------------------------------------------------------------
+        self.__record_count += 1
+        self.__current_index += 1
+        record = self.__create_record(
+                defaultData = defaultData,
+                position    = self.__current_index)
+        self.__sync()
+        return record
 
-  def duplicateRecord (self, exclude = [], include = []):
-    """
-    Create a new record and initialize it with field values from the record at
-    the current cursor position.
 
-    The cursor is moved to the newly inserted record.
+    # -------------------------------------------------------------------------
+    # Create a new record with a copy of the existing one
+    # -------------------------------------------------------------------------
 
-    @param exclude: list of fields not to copy.
-    @param include: list of fields to copy. An empty list means to copy all
-      fields except primary key fields and rowid fields, which are never copied
-      anyway.
-    @return: the newly inserted record.
-    @raise L{Exceptions.ReadOnlyInsertError}: if the ResultSet is read only.
-    """
+    def duplicateRecord(self, exclude = [], include = []):
+        """
+        Create a new record and initialize it with field values from the record
+        at the current cursor position.
 
-    checktype (exclude, list)
-    checktype (include, list)
+        The cursor is moved to the newly inserted record.
 
-    current = self.current
-    inserted = self.insertRecord ()
+        @param exclude: list of fields not to copy.
+        @param include: list of fields to copy. An empty list means to copy all
+            fields except primary key fields and rowid fields, which are never
+            copied anyway.
+        @return: the newly inserted record.
+        @raise L{Exceptions.ReadOnlyInsertError}: if the ResultSet is read
+            only.
+        """
 
-    # If include= is specified, then that is our base list.
-    # Otherwise, get the base list as the fields in the table
-    if include:
-      fields = list (include)
-    else:
-      fields = current.keys ()
+        checktype(exclude, list)
+        checktype(include, list)
 
-    # Exclude all the fields in exclude=
-    for field in exclude:
-      fields.remove (field)
+        current = self.current
+        inserted = self.insertRecord()
 
-    # Do not duplicate the primary key fields,
-    # unless it was named in the include= parameter
-    for field in self.__primarykeyFields:
-      if field not in include and field in fields:
-        fields.remove (field)
+        # If include= is specified, then that is our base list.
+        # Otherwise, get the base list as the fields in the table
+        if include:
+            fields = list(include)
+        else:
+            fields = current.keys()
 
-    # Never include the rowid
-    field = self.__rowidField
-    if field and field in fields:
-      fields.remove (field)
+        # Exclude all the fields in exclude=
+        for field in exclude:
+            fields.remove(field)
 
-    # Copy the fields over
-    for field in fields:
-      inserted[field] = current[field]
+        # Do not duplicate the primary key fields,
+        # unless it was named in the include= parameter
+        for field in self.__primarykeyFields:
+            if field not in include and field in fields:
+                fields.remove(field)
 
-    return inserted
+        # Never include the rowid
+        field = self.__rowidField
+        if field and field in fields:
+            fields.remove(field)
 
+        # Copy the fields over
+        for field in fields:
+            inserted[field] = current[field]
 
-  # ---------------------------------------------------------------------------
-  # Find out if there is anything to post
-  # ---------------------------------------------------------------------------
+        return inserted
 
-  def isPending (self):
-    """
-    Return True if the resultset or a detail resultset has uncommitted changes.
-    """
-    for rec in self.__cachedRecords:
-      if rec.isPending ():
-        return True
-    return False
 
+    # -------------------------------------------------------------------------
+    # Find out if there is anything to post
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Post changes to the backend
-  # ---------------------------------------------------------------------------
+    def isPending(self):
+        """
+        Return True if the resultset or a detail resultset has uncommitted
+        changes.
+        """
+        for rec in self.__cached_records:
+            if rec.isPending():
+                return True
+        return False
 
-  def post (self, fkData = {}):
-    """
-    Post all local changes to the backend.
 
-    This method leaves the ResultSet in an incomplete state.  After every call
-    to post, L{requery} must be called.  If the operation should be committed,
-    the L{Connection.commit} method can be called between post and requery.
+    # -------------------------------------------------------------------------
+    # Post changes to the backend
+    # -------------------------------------------------------------------------
 
-    This method does not change the status of any record, so in case of an
-    exception, it can be just called again.
+    def post(self, fkData = {}):
+        """
+        Post all local changes to the backend.
 
-    @param fkData: fieldname/value dictionary for foreign key fields. Used
-      internally for detail resultsets in a master/detail relationship.
-    @raise Exception: if posting the changes to the backend fails for any
-      reason. The exact exception classes depend on the backend.
-    """
+        This method leaves the ResultSet in an incomplete state.  After every
+        call to post, L{requery} must be called.  If the operation should be
+        committed, the L{Connection.commit} method can be called between post
+        and requery.
 
-    # save current record position
-    currentRecord = self.__currentRecord
+        This method does not change the status of any record, so in case of an
+        exception, it can be just called again.
 
-    # post our changes
-    try:
-      # we move the cursor along while we post, so triggers see the posting
-      # record as the current record
-      self.__currentRecord = 0
-      while self.__currentRecord < len (self.__cachedRecords):
-        self.current = self.__cachedRecords [self.__currentRecord]
-        if self.current.isPending () and not self.current.isVoid ():
+        @param fkData: fieldname/value dictionary for foreign key fields. Used
+            internally for detail resultsets in a master/detail relationship.
+        @raise Exception: if posting the changes to the backend fails for any
+            reason. The exact exception classes depend on the backend.
+        """
 
-          # activate all matching detail resultsets so that committ triggers
-          # see the correct details
-          self.current._activate ()
+        # save current record position
+        currentRecord = self.__current_index
 
-          # Set the foreign keys for inserted records in case the master 
changed
-          # its primary key in a commit trigger
-          if self.current.isInserted ():
-            for (fieldname, value) in fkData.items ():
-              self.current [fieldname] = value
+        # post our changes
+        try:
+            # we move the cursor along while we post, so triggers see the
+            # posting record as the current record
+            self.__current_index = 0
+            while self.__current_index < len(self.__cached_records):
+                self.current = self.__cached_records[self.__current_index]
+                if self.current.isPending() and not self.current.isVoid():
 
-          # write changes to the backend
-          self.current._post ()
+                    # activate all matching detail resultsets so that commit
+                    # triggers see the correct details
+                    self.current._activate()
 
-        self.__currentRecord += 1
+                    # Set the foreign keys for inserted records in case the
+                    # master changed its primary key in a commit trigger
+                    if self.current.isInserted():
+                        for (fieldname, value) in fkData.items():
+                            self.current[fieldname] = value
 
-    except:
-      # If any error happened on writing to the backend, move the UI to the
-      # record that caused the error
-      self.__sync ()
-      raise
+                    # write changes to the backend
+                    self.current._post()
 
-    # Restore current record position
-    self.__currentRecord = currentRecord
+                self.__current_index += 1
 
+        except:
+            # If any error happened on writing to the backend, move the UI to
+            # the record that caused the error
+            self.__sync()
+            raise
 
-  # ---------------------------------------------------------------------------
-  # Sync resultset with backend, and sync listeners with resultset
-  # ---------------------------------------------------------------------------
+        # Restore current record position
+        self.__current_index = currentRecord
 
-  def requery (self, commit):
-    """
-    Synchronize everything after a call to L{post}.
 
-    This method must be called after each call to the L{post} method. If the
-    operation should be committed, the L{Connection.commit} method can be
-    called between post and requery.
+    # -------------------------------------------------------------------------
+    # Sync resultset with backend, and sync listeners with resultset
+    # -------------------------------------------------------------------------
 
-    Note that this method does not only requery changes from the database, but
-    it also updates the record status for all added, modified or deleted
-    records. So, requery must always be called after L{post}, even if the
-    requery feature is not used.
+    def requery(self, commit):
+        """
+        Synchronize everything after a call to L{post}.
 
-    @param commit: indicate whether a commit was run since the last L{post}
-      call.
+        This method must be called after each call to the L{post} method. If
+        the operation should be committed, the L{Connection.commit} method can
+        be called between post and requery.
 
-    @raise Exception: if querying the records from the backend fails for any
-      reason. The exact exception classes depend on the backend.
-    """
+        Note that this method does not only requery changes from the database,
+        but it also updates the record status for all added, modified or
+        deleted records. So, requery must always be called after L{post}, even
+        if the requery feature is not used.
 
-    index = 0
-    while index < len (self.__cachedRecords):
-      record = self.__cachedRecords [index]
-      if record._needsRequery (commit):
-        if ((record.isEmpty () or record.isVoid () or record.isDeleted ()) \
-            and self.__connection is not None):
-          self.__removeRecord (index)
+        @param commit: indicate whether a commit was run since the last L{post}
+            call.
+
+        @raise Exception: if querying the records from the backend fails for
+            any reason. The exact exception classes depend on the backend.
+        """
+
+        index = 0
+        while index < len(self.__cached_records):
+            record = self.__cached_records[index]
+            if record._needsRequery(commit):
+                if ((record.isEmpty() or record.isVoid() \
+                                or record.isDeleted()) \
+                        and self.__connection is not None):
+                    self.__remove_record(index)
+                else:
+                    record._requery(commit)
+                    index += 1
+            else:
+                index += 1
+
+        self.__sync()
+
+
+    # -------------------------------------------------------------------------
+    # Merge another ResultSet into this one
+    # -------------------------------------------------------------------------
+
+    def _merge(self, otherResultSet):
+        """
+        Merge another (more current) ResultSet into this one.
+
+        This function is used by the master RecordSet to update it's detail
+        ResultSets after it has been committed to the backend (and some backend
+        triggers might have changed the details).
+
+        @param otherResultSet: the other ResultSet to merge
+        """
+
+        if self.__primarykeyFields:
+            keyFields = self.__primarykeyFields
+        elif self.__rowidField:
+            keyFields = [self.__rowidField]
         else:
-          record._requery (commit)
-          index += 1
-      else:
-        index += 1
+            return
 
-    self.__sync ()
+        # Make sure that all records are cached
+        while self.__cache_next_record():
+            pass
 
+        newData = otherResultSet.getDictArray(keyFields, self.__boundFields)
 
-  # ---------------------------------------------------------------------------
-  # Merge another ResultSet into this one
-  # ---------------------------------------------------------------------------
+        index = 0
+        for record in self.__cached_records[:]:
+            if record.isEmpty():
+                # keep empty record in old ResultSet
+                index += 1
+                continue
+            d = newData
+            for field in keyFields:
+                if d.has_key(record[field]):
+                    d = d[record[field]]
+                else:
+                    # Record is not in newData - it has been deleted meanwhile
+                    d = None
+                    break
+            if d:
+                # Found in newData - update RecordSet
+                record._initialDataFromDict(d)
+                # And set to empty dict to indicate it has been processed
+                d.clear()
+                index += 1
+            else:
+                # Not found in newData - delete it
+                self.__remove_record(index)
 
-  def _merge (self, otherResultSet):
-    """
-    Merge another (more current) ResultSet into this one.
+        # Add the rest of newData - it has been inserted
+        # Convert the multi dimensional dictionary into a list
+        l = newData.values()
+        for field in keyFields[1:]:
+            l2 = []
+            for d in l:
+                l2 += d.values()
+            l = l2
+        # Now for all non-empty dicts, append a new record
+        for row in l:
+            if row:
+                record = self.__create_record(initialData = row)
 
-    This function is used by the master RecordSet to update it's detail
-    ResultSets after it has been committed to the backend (and some backend
-    triggers might have changed the details).
+        self.__sync()
 
-    @param otherResultSet: the other ResultSet to merge
-    """
 
-    if self.__primarykeyFields:
-      keyFields = self.__primarykeyFields
-    elif self.__rowidField:
-      keyFields = [self.__rowidField]
-    else:
-      return
+    # -------------------------------------------------------------------------
+    # Query the backend again with the same query as the original one
+    # -------------------------------------------------------------------------
 
-    # Make sure that all records are cached
-    while self.__cacheNextRecord ():
-      pass
+    def _refresh(self):
+        """
+        Repeat the last query, updating the result set with current data from
+        the backend.
 
-    newData = otherResultSet.getDictArray (keyFields, self.__boundFields)
+        This method issues a new query against the backend which is identical
+        to the last query that was used to build this result set. Data from
+        this new query then replaces the data currently held in the result set.
+        If there were unsaved changes before, they are lost.  This method tries
+        to set the current record pointer to the same record as it was before.
+        """
+        # Remember current record
+        old_current = self.current
 
-    index = 0
-    for record in self.__cachedRecords [:]:
-      if record.isEmpty ():
-        # keep empty record in old ResultSet
-        index += 1
-        continue
-      d = newData
-      for field in keyFields:
-        if d.has_key (record [field]):
-          d = d [record [field]]
+        # Fire the query with the remembered parameters
+        self.query(self.__lastquery_type, self.__lastquery_cache,
+                **self.__lastquery_kwargs)
+
+        # Set curent record pointer to old current record. This impiles
+        # fetching through the new result set until we find it.
+        if self.__rowidField:
+            keyfields = {self.__rowidField: old_current[self.__rowidField]}
+        elif self.__primarykeyFields:
+            keyfields = {}
+            for field in self.__primarykeyFields:
+                keyfields[field] = old_current[field]
         else:
-          # Record is not in newData - it has been deleted meanwhile
-          d = None
-          break
-      if d:
-        # Found in newData - update RecordSet
-        record._initialDataFromDict (d)
-        # And set to empty dict to indicate it has been processed
-        d.clear ()
-        index += 1
-      else:
-        # Not found in newData - delete it
-        self.__removeRecord (index)
+            keyfields = {}
+            for field in self.__boundFields:
+                keyfields[field] = old_current[field]
+        if keyfields:
+            if self.findRecord(keyfields):
+                # We have found the old current record, nothing more to do
+                pass
+            else:
+                # Old current record is not there in new data
+                # FIXME: Try to navigate to first record that would follow the
+                # current record according to current sort order
+                self.firstRecord()
 
-    # Add the rest of newData - it has been inserted
-    # Convert the multi dimensional dictionary into a list
-    l = newData.values ()
-    for field in keyFields [1:]:
-      l2 = []
-      for d in l:
-        l2 += d.values ()
-      l = l2
-    # Now for all non-empty dicts, append a new record
-    for row in l:
-      if row:
-        record = self.__createRecord (initialData = row)
 
-    self.__sync ()
+    # -------------------------------------------------------------------------
+    # Close the result set
+    # -------------------------------------------------------------------------
 
+    def close(self):
+        """
+        Close the database connection.
+        """
 
-  # ---------------------------------------------------------------------------
-  # Close the result set
-  # ---------------------------------------------------------------------------
+        self._close_()
 
-  def close (self):
-    """
-    Close the database connection.
-    """
 
-    self._close_ ()
+    # -------------------------------------------------------------------------
+    # Sync self.current with self.__current_index and adjust detail resultsets
+    # and the user interface
+    # -------------------------------------------------------------------------
 
+    def __sync(self):
 
-  # ---------------------------------------------------------------------------
-  # Sync self.current with self.__currentRecord and adjust detail resultsets
-  # and the user interface
-  # ---------------------------------------------------------------------------
+        old_current = self.current
+        if self.__current_index == -1:
+            self.current = None
+        else:
+            self.current = self.__cached_records[self.__current_index]
 
-  def __sync (self):
+        # If the current record has *really* changed (this method can be called
+        # for non-changing records after requery or merge) to a new current
+        # record, bring all detail records in sync.
+        if self.current and self.current != old_current:
+            # If the cursor moved out of an empty record, throw it away.
+            if old_current and old_current.isEmpty():
+                if old_current in self.__cached_records:
+                    index = self.__cached_records.index(old_current)
+                    self.__remove_record(index)
+            self.current._activate()
 
-    oldCurrent = self.current
-    if self.__currentRecord == -1:
-      self.current = None
-    else:
-      self.current = self.__cachedRecords [self.__currentRecord]
+        if self.__eventController is not None:
+            self.__eventController.dispatchEvent('dsCursorMoved')
 
-    # If the current record has *really* changed (this method can be called for
-    # non-changing records after requery or merge) to a new current record,
-    # bring all detail records in sync.
-    if self.current and self.current != oldCurrent:
-      # If the cursor moved out of an empty record, throw it away.
-      if oldCurrent and oldCurrent.isEmpty ():
-        if oldCurrent in self.__cachedRecords:
-          self.__removeRecord (self.__cachedRecords.index (oldCurrent))
-      self.current._activate ()
 
-    if self.__eventController is not None:
-      self.__eventController.dispatchEvent ('dsCursorMoved')
+    # -------------------------------------------------------------------------
+    # Load next record from backend into cache
+    # -------------------------------------------------------------------------
 
+    def __cache_next_record(self):
 
-  # ---------------------------------------------------------------------------
-  # Load next record from backend into cache
-  # ---------------------------------------------------------------------------
+        if not self.__generator:
+            return False
 
-  def __cacheNextRecord (self):
+        try:
+            row = self.__generator.next()
+        except StopIteration:
+            return False
 
-    if not self.__generator:
-      return False
+        record = self.__create_record(initialData = row)
 
-    try:
-      row = self.__generator.next ()
-    except StopIteration:
-      return False
+        return True
 
-    record = self.__createRecord (initialData = row)
 
-    return True
+    # -------------------------------------------------------------------------
+    # Create a new record in the cache
+    # -------------------------------------------------------------------------
 
+    def __create_record(self, initialData = {}, defaultData = {},
+            position = None):
 
-  # ---------------------------------------------------------------------------
-  # Create a new record in the cache
-  # ---------------------------------------------------------------------------
+        __defaultData = self.__defaultData.copy()
+        __defaultData.update(defaultData)
 
-  def __createRecord (self, initialData = {}, defaultData = {},
-      position = None):
+        record = RecordSet(
+                initialData      = initialData,
+                defaultData      = __defaultData,
+                connection       = self.__connection,
+                tablename        = self.__tablename,
+                rowidField       = self.__rowidField,
+                primarykeyFields = self.__primarykeyFields,
+                primarykeySeq    = self.__primarykeySeq,
+                boundFields      = self.__boundFields,
+                requery          = self.__requery,
+                readonly         = self.__readonly,
+                details          = self.__details,
+                eventController  = self.__eventController)
 
-    __defaultData = self.__defaultData.copy ()
-    __defaultData.update (defaultData)
+        if position is None:
+            self.__cached_records.append(record)
+        else:
+            self.__cached_records.insert(position, record)
 
-    record = RecordSet (
-        initialData      = initialData,
-        defaultData      = __defaultData,
-        connection       = self.__connection,
-        tablename        = self.__tablename,
-        rowidField       = self.__rowidField,
-        primarykeyFields = self.__primarykeyFields,
-        primarykeySeq    = self.__primarykeySeq,
-        boundFields      = self.__boundFields,
-        requery          = self.__requery,
-        readonly         = self.__readonly,
-        details          = self.__details,
-        eventController  = self.__eventController)
+        return record
 
-    if position is None:
-      self.__cachedRecords.append (record)
-    else:
-      self.__cachedRecords.insert (position, record)
 
-    return record
+    # -------------------------------------------------------------------------
+    # Remove a record from the cache
+    # -------------------------------------------------------------------------
 
+    def __remove_record(self, index):
 
-  # ---------------------------------------------------------------------------
-  # Remove a record from the cache
-  # ---------------------------------------------------------------------------
+        self.__cached_records.pop(index)
+        self.__record_count -= 1
 
-  def __removeRecord (self, index):
+        # if a record preceding the cursor position was deleted, move cursor
+        # position along
+        if index <= self.__current_index:
+            self.__current_index -= 1
 
-    self.__cachedRecords.pop (index)
-    self.__recordCount -= 1
+        # ... but don't move below 0 unless there is *really* no record left
+        if self.__current_index < 0 and self.__record_count:
+            self.__current_index = 0
 
-    # if a record preceding the cursor position was deleted, move cursor
-    # position along
-    if index <= self.__currentRecord:
-      self.__currentRecord -= 1
 
-    # ... but don't move below 0 unless there is *really* no record left
-    if self.__currentRecord < 0 and self.__recordCount:
-      self.__currentRecord = 0
+    # -------------------------------------------------------------------------
+    # Virtual methods
+    # -------------------------------------------------------------------------
 
+    def _query_static_(self, connection, data):
+        """
+        Execute a query.
 
-  # ---------------------------------------------------------------------------
-  # Virtual methods
-  # ---------------------------------------------------------------------------
+        Descendants would rather overwrite _query_object_ and/or _query_sql_.
+        Parameters depend on the type of query (object/sql).
+        """
+        self.__static_data = data
 
-  def _query_static_ (self, connection, data):
-    """
-    Execute a query.
+    # -------------------------------------------------------------------------
 
-    Descendants would rather overwrite _query_object_ and/or _query_sql_.
-    Parameters depend on the type of query (object/sql).
-    """
-    self.__staticData = data
+    def _count_(self):
+        """
+        Return the number of records returned by the query.
 
-  # ---------------------------------------------------------------------------
+        @return: Number of records that will be yielded by @L{_fetch_}.
+        """
+        return len(self.__static_data)
 
-  def _count_ (self):
-    """
-    Return the number of records returned by the query.
+    # -------------------------------------------------------------------------
 
-    @return: Number of records that will be yielded by @L{_fetch_}.
-    """
-    return len (self.__staticData)
+    def _fetch_(self, cachesize):
+        """
+        Yield records from the query.
 
-  # ---------------------------------------------------------------------------
+        Descendants must overwrite this function to return a sequence of
+        fieldname/value dictionaries.
 
-  def _fetch_ (self, cachesize):
-    """
-    Yield records from the query.
+        @param cachesize: Recommended cache size the driver should use to
+            communicate with the backend.
+        @return: A generator for fieldname/value dictionaries.
+        """
+        for row in self.__static_data:
+            yield row
 
-    Descendants must overwrite this function to return a sequence of
-    fieldname/value dictionaries.
+    # -------------------------------------------------------------------------
 
-    @param cachesize: Recommended cache size the driver should use to
-    communicate with the backend.
-    @return: A generator for fieldname/value dictionaries.
-    """
-    for row in self.__staticData:
-      yield row
+    def _close_(self):
+        """
+        Close the cursor.
 
-  # ---------------------------------------------------------------------------
-
-  def _close_ (self):
-    """
-    Close the cursor.
-
-    Descendants can overwrite this function to clean up things done in the
-    _query_ functions.
-    """
-    pass
+        Descendants can overwrite this function to clean up things done in the
+        _query_ functions.
+        """
+        pass





reply via email to

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