[gnue] r9784 - in trunk/gnue-appserver: src tests

[email protected]
Newsgroups gmane.comp.cms.gnue.cvs
Message-ID <[email protected]>
Author: johannes
Date: 2007-09-26 08:35:03 -0500 (Wed, 26 Sep 2007)
New Revision: 9784

Modified:
   trunk/gnue-appserver/src/data.py
   trunk/gnue-appserver/tests/data.py
Log:
Fixed dirty reads ?!


Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py	2007-09-26 12:44:15 UTC (rev 9783)
+++ trunk/gnue-appserver/src/data.py	2007-09-26 13:35:03 UTC (rev 9784)
@@ -1264,17 +1264,17 @@
           next_add = None
 
       for backend_record in [self.__buildRecords(r) for r in self.__rawdata]:
-
           # if there are any uncommitted new records, insert them at the
           # correct position
           if next_add is not None:
               gnue_id = backend_record._row
-              while next_add < SortRecord(gnue_id,
+              while next_add and next_add < SortRecord(gnue_id,
                       self.__getSortSequence(gnue_id)):
                   self.__add.pop(0)
                   self.__added += 1
                   yield record(self.__cache, self.__connections,
-                          self.__database, self.__getMasterTable(), next_add)
+                          self.__database, self.__getMasterTable(),
+                          next_add.row)
                   if self.__add:
                       next_add = SortRecord(self.__add[0],
                               self.__getSortSequence(self.__add[0]))
@@ -1287,7 +1287,17 @@
 
           yield backend_record
 
+      # If there new records left yield them as well
+      while self.__add:
+        next = self.__add[0]
+        self.__add.pop(0)
+        self.__added += 1
+        yield record(self.__cache, self.__connections,
+                     self.__database, self.__getMasterTable(), next)
 
+
+
+
   # ---------------------------------------------------------------------------
   # Close the record set
   # ---------------------------------------------------------------------------
@@ -1650,16 +1660,17 @@
     result = []
     append = result.append
 
-    for element in self.__order:
-      field      = element ['name']
-      direction  = element.get ('descending') or False
-      ignorecase = element.get ('ignorecase') or False
-      value = self.__getPathValue (row, self.__getPropertyPath (field))
+    if self.__order:
+      for element in self.__order:
+        field      = element ['name']
+        direction  = element.get ('descending') or False
+        ignorecase = element.get ('ignorecase') or False
+        value = self.__getPathValue (row, self.__getPropertyPath (field))
 
-      if ignorecase and hasattr (value, 'lower'):
-        value = value.lower ()
+        if ignorecase and hasattr (value, 'lower'):
+          value = value.lower ()
 
-      append ((value, direction))
+        append ((value, direction))
 
     return result
 

Modified: trunk/gnue-appserver/tests/data.py
===================================================================
--- trunk/gnue-appserver/tests/data.py	2007-09-26 12:44:15 UTC (rev 9783)
+++ trunk/gnue-appserver/tests/data.py	2007-09-26 13:35:03 UTC (rev 9784)
@@ -31,674 +31,683 @@
 # TestCase for _cache class
 # =============================================================================
 
-class CachingTestCase (unittest.TestCase):
-  """
-  TestCase for the low-level class _cache
-  """
-
-  # ---------------------------------------------------------------------------
-  # Test Case Setup
-  # ---------------------------------------------------------------------------
-
-  def setUp (self):
+class CachingTestCase(unittest.TestCase):
     """
-    Create a new instance of the cache
+    TestCase for the low-level class _cache
     """
 
-    self.cache = data._cache ()
+    # -------------------------------------------------------------------------
+    # Test Case Setup
+    # -------------------------------------------------------------------------
 
+    def setUp(self):
+        """
+        Create a new instance of the cache
+        """
 
-  # ---------------------------------------------------------------------------
-  # Is the cache cleaned well ?
-  # ---------------------------------------------------------------------------
+        self.cache = data._cache()
 
-  def test_cacheClean (self):
-    """
-    Test if the cache is cleaned well
-    """
 
-    table = u'FOO'
-    rows  = [u'100', u'200']
+    # -------------------------------------------------------------------------
+    # Is the cache cleaned well ?
+    # -------------------------------------------------------------------------
 
-    # Write data into clean cache. The cache should not be dirty at all
-    for row in rows:
-      self.cache.write_clean (table, row, [(u'foo', 1)])
+    def test_cacheClean(self):
+        """
+        Test if the cache is cleaned well
+        """
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    self.assertEqual (result, [])
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {})
+        table = u'FOO'
+        rows  = [u'100', u'200']
 
-    # Now write data to dirty cache, which will render the records as 'changed'
-    for row in rows:
-      self.cache.write_dirty (table, row, u'foo', 1)
+        # Write data into clean cache. The cache should not be dirty at all
+        for row in rows:
+            self.cache.write_clean(table, row, [(u'foo', 1)])
 
-    self.cache.insertRecord (u'BAR', u'200')
-    self.cache.initialized (u'BAR', u'200')
-    self.cache.insertRecord (u'FOO', u'771')
-    self.cache.initialized (u'FOO', u'771')
-    self.cache.write_dirty (u'FOO', u'771', u'val', 5)
+        result = self.__orderTables(self.cache.dirtyTables())
+        self.assertEqual(result, [])
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted, {})
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(u'BAR', u'200', 'initialized', [(u'gnue_id', u'200')]),
-           (u'FOO', u'100', 'changed', [(u'foo', 1)]),
-           (u'FOO', u'200', 'changed', [(u'foo', 1)]),
-           (u'FOO', u'771', 'inserted', [(u'gnue_id', u'771'), (u'val', 5)])]
+        # Now write data to dirty cache, which will render the records as
+        # 'changed'
+        for row in rows:
+            self.cache.write_dirty(table, row, u'foo', 1)
 
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.inserted, {u'BAR-200': (u'BAR', u'200'),
-        u'FOO-771': (u'FOO', u'771')})
-    self.assertEqual (self.cache.deleted, {})
+        self.cache.insertRecord(u'BAR', u'200')
+        self.cache.initialized(u'BAR', u'200')
+        self.cache.insertRecord(u'FOO', u'771')
+        self.cache.initialized(u'FOO', u'771')
+        self.cache.write_dirty(u'FOO', u'771', u'val', 5)
 
-    # Cancelling the current atomic operation should make the cache clean again
-    self.cache.cancel ()
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(u'BAR', u'200', 'initialized', [(u'gnue_id', u'200')]),
+               (u'FOO', u'100', 'changed', [(u'foo', 1)]),
+               (u'FOO', u'200', 'changed', [(u'foo', 1)]),
+               (u'FOO', u'771', 'inserted', [(u'gnue_id', u'771'),(u'val', 5)])]
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    self.assertEqual (result, [])
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {})
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.inserted, {u'BAR-200': (u'BAR', u'200'),
+            u'FOO-771': (u'FOO', u'771')})
+        self.assertEqual(self.cache.deleted, {})
 
-    # Insert another three records. One is changed into 'inserted' state,
-    # another one is left at 'initialized' and the last one is left at
-    # 'initializing'
-    self.cache.clear ()
+        # Cancelling the current atomic operation should make the cache clean
+        # again
+        self.cache.cancel()
 
-    self.cache.insertRecord (table, u'1')
-    self.cache.initialized (table, u'1')
-    self.cache.write_dirty (table, u'1', u'foo', 1)
+        result = self.__orderTables(self.cache.dirtyTables())
+        self.assertEqual(result, [])
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted, {})
 
-    self.cache.insertRecord (table, u'2')
-    self.cache.initialized (table, u'2')
+        # Insert another three records. One is changed into 'inserted' state,
+        # another one is left at 'initialized' and the last one is left at
+        # 'initializing'
+        self.cache.clear()
 
-    self.cache.insertRecord (table, u'3')
+        self.cache.insertRecord(table, u'1')
+        self.cache.initialized(table, u'1')
+        self.cache.write_dirty(table, u'1', u'foo', 1)
 
-    exp = [(table, u'1', 'inserted', [(u'foo', 1), (u'gnue_id', u'1')]),
-           (table, u'2', 'initialized', [(u'gnue_id', u'2')]),
-           (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
-    self.assertEqual (exp, self.__orderTables (self.cache.dirtyTables ()))
+        self.cache.insertRecord(table, u'2')
+        self.cache.initialized(table, u'2')
 
-    self.cache.makeClean (table, u'1')
+        self.cache.insertRecord(table, u'3')
 
-    # Now clear all 'clean' stuff
-    exp = [(table, u'2', 'initialized', [(u'gnue_id', u'2')]),
-           (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
-    self.cache.clear (True)
-    self.assertEqual (exp, self.__orderTables (self.cache.dirtyTables ()))
+        exp = [(table, u'1', 'inserted', [(u'foo', 1), (u'gnue_id', u'1')]),
+               (table, u'2', 'initialized', [(u'gnue_id', u'2')]),
+               (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
+        self.assertEqual(exp, self.__orderTables(self.cache.dirtyTables()))
 
-    # And now everything should really go away
-    self.cache.clear ()
-    self.assertEqual (self.cache.dirtyTables (), {})
+        self.cache.makeClean(table, u'1')
 
+        # Now clear all 'clean' stuff
+        exp = [(table, u'2', 'initialized', [(u'gnue_id', u'2')]),
+               (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
+        self.cache.clear(True)
+        self.assertEqual(exp, self.__orderTables(self.cache.dirtyTables()))
 
-    
-  # ---------------------------------------------------------------------------
-  # Perform insertions
-  # ---------------------------------------------------------------------------
+        # And now everything should really go away
+        self.cache.clear()
+        self.assertEqual(self.cache.dirtyTables(), {})
 
-  def test_cacheInsertions (self):
-    """
-    Perform variouse test regarding data insertion
-    """
 
-    self.cache.clear ()
 
-    table = u'table'
-    row   = u'100'
-    row2  = u'200'
+    # -------------------------------------------------------------------------
+    # Perform insertions
+    # -------------------------------------------------------------------------
 
-    # We cannot insert a record if it's already available
-    self.cache.write_dirty (table, row, u'foo', 1)
-    self.assertRaises (data.DuplicateRecordError, self.cache.insertRecord,
-        table, row)
+    def test_cacheInsertions(self):
+        """
+        Perform variouse test regarding data insertion
+        """
 
-    self.cache.clear ()
+        self.cache.clear()
 
-    # Insert a record, change and confirm it
-    self.cache.insertRecord (table, row)
-    self.cache.initialized (table, row)
-    self.cache.write_dirty (table, row, u'foo', 1)
-    self.cache.confirm ()
+        table = u'table'
+        row   = u'100'
+        row2  = u'200'
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
-    self.assertEqual (self.cache.deleted, {})
+        # We cannot insert a record if it's already available
+        self.cache.write_dirty(table, row, u'foo', 1)
+        self.assertRaises(data.DuplicateRecordError, self.cache.insertRecord,
+            table, row)
 
-    # change it again, and insert another row. We won't set the latter one to
-    # initialized so it does not get into 'inserted' state
-    self.cache.write_dirty (table, row, u'foo', 2)
-    self.cache.insertRecord (table, row2)
-    self.cache.write_dirty (table, row2, u'bar', 2)
+        self.cache.clear()
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
-           (table, row2, 'initializing', [(u'bar', 2), (u'gnue_id', row2)])]
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.inserted, {u'table-100': (table, row),
-                                            u'table-200': (table, row2)})
-    self.assertEqual (self.cache.deleted, {})
+        # Insert a record, change and confirm it
+        self.cache.insertRecord(table, row)
+        self.cache.initialized(table, row)
+        self.cache.write_dirty(table, row, u'foo', 1)
+        self.cache.confirm()
 
-    # Now delete the second record
-    self.cache.deleteRecord (table, row2)
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+        self.assertEqual(self.cache.deleted, {})
 
-    # After deleting the previously inserted record the only record left should
-    # be the inserted one
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
-           (table, row2, 'deleted', [(u'bar', 2), (u'gnue_id', None)])]
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
-    self.assertEqual (self.cache.deleted, {})
+        # change it again, and insert another row. We won't set the latter one to
+        # initialized so it does not get into 'inserted' state
+        self.cache.write_dirty(table, row, u'foo', 2)
+        self.cache.insertRecord(table, row2)
+        self.cache.write_dirty(table, row2, u'bar', 2)
 
-    # cancel the atomic operation. This should give us the state from the last
-    # call of confirm ()
-    self.cache.cancel ()
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
+               (table, row2, 'initializing', [(u'bar', 2), (u'gnue_id', row2)])]
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.inserted, {u'table-100': (table, row),
+                                                u'table-200': (table, row2)})
+        self.assertEqual(self.cache.deleted, {})
 
+        # Now delete the second record
+        self.cache.deleteRecord(table, row2)
 
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
-    self.assertEqual (self.cache.deleted, {})
+        # After deleting the previously inserted record the only record left
+        # should be the inserted one
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
+               (table, row2, 'deleted', [(u'bar', 2), (u'gnue_id', None)])]
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+        self.assertEqual(self.cache.deleted, {})
 
-    # Now simulate a commit which uses makeClean () to make a given record
-    # clean
-    self.cache.makeClean (table, row)
-    self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), [])
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {})
+        # cancel the atomic operation. This should give us the state from the
+        # last call of confirm()
+        self.cache.cancel()
 
-    # Add a new record, confirm it and then delete it
-    self.cache.clear ()
 
-    self.cache.insertRecord (table, row)
-    self.cache.initialized (table, row)
-    self.cache.write_dirty (table, row, u'name', 'foobar')
-    self.cache.confirm ()
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+        self.assertEqual(self.cache.deleted, {})
 
-    exp = [(table, row, 'inserted', [(u'gnue_id', row), (u'name', 'foobar')])]
-    self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp)
-    self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
+        # Now simulate a commit which uses makeClean() to make a given record
+        # clean
+        self.cache.makeClean(table, row)
+        self.assertEqual(self.__orderTables(self.cache.dirtyTables()), [])
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted, {})
 
-    self.cache.deleteRecord (table, row)
+        # Add a new record, confirm it and then delete it
+        self.cache.clear()
 
-    exp = [(table, row, 'deleted', [(u'gnue_id', None), (u'name', 'foobar')])]
-    self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp)
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {})
+        self.cache.insertRecord(table, row)
+        self.cache.initialized(table, row)
+        self.cache.write_dirty(table, row, u'name', 'foobar')
+        self.cache.confirm()
 
+        exp = [(table, row, 'inserted', [(u'gnue_id', row), (u'name', 'foobar')])]
+        self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp)
+        self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
 
+        self.cache.deleteRecord(table, row)
 
+        exp = [(table, row, 'deleted',
+               [(u'gnue_id', None), (u'name', 'foobar')])]
+        self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp)
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted, {})
 
-  # ---------------------------------------------------------------------------
-  # Perform tests with modifications of records
-  # ---------------------------------------------------------------------------
 
-  def test_cacheModification (self):
-    """
-    Perfrom tests with mixed modification operations
-    """
+    # -------------------------------------------------------------------------
+    # Perform tests with modifications of records
+    # -------------------------------------------------------------------------
 
-    self.cache.clear ()
+    def test_cacheModification(self):
+        """
+        Perfrom tests with mixed modification operations
+        """
 
-    table = u'FOO'
-    row   = u'100'
+        self.cache.clear()
 
-    # First add some clean data to the cache
-    self.cache.write_clean (table, row, [(u'foo', 1)])
+        table = u'FOO'
+        row   = u'100'
 
-    # Now change an 'existing' record and cancel that operation
-    self.cache.write_dirty (table, row, u'bar', 2)
-    self.cache.write_dirty (table, row, u'foo', 100)
-    self.cache.cancel ()
+        # First add some clean data to the cache
+        self.cache.write_clean(table, row, [(u'foo', 1)])
 
-    # The cached (current) value of 'foo' should be still the clean value, and
-    # there must not be any 'dirty' data atm
-    self.assertEqual (self.cache.read (table, row, u'foo'), 1)
-    self.assertEqual (self.cache.dirtyTables (), {})
+        # Now change an 'existing' record and cancel that operation
+        self.cache.write_dirty(table, row, u'bar', 2)
+        self.cache.write_dirty(table, row, u'foo', 100)
+        self.cache.cancel()
 
-    # Change the record again; now it should have the state 'changed'
-    self.cache.write_dirty (table, row, u'foo', 100)
-    result = self.__orderTables (self.cache.dirtyTables ())
-    exp = [(table, row, 'changed', [(u'foo', 100)])]
-    self.assertEqual (result, exp)
-    self.cache.confirm ()
+        # The cached (current) value of 'foo' should be still the clean value,
+        # and there must not be any 'dirty' data atm
+        self.assertEqual(self.cache.read(table, row, u'foo'), 1)
+        self.assertEqual(self.cache.dirtyTables(), {})
 
-    # Calling initialized () for a record which wasn't inserted before must
-    # raise an exception
-    self.assertRaises (data.StateChangeError, self.cache.initialized,
-                       table, row)
+        # Change the record again; now it should have the state 'changed'
+        self.cache.write_dirty(table, row, u'foo', 100)
+        result = self.__orderTables(self.cache.dirtyTables())
+        exp = [(table, row, 'changed', [(u'foo', 100)])]
+        self.assertEqual(result, exp)
+        self.cache.confirm()
 
-    # Now delete the record. It will change it's state and shows up in the
-    # deletion queue
-    self.cache.deleteRecord (table, row)
-    exp2 = [(table, row, 'deleted', [(u'foo', 100), (u'gnue_id', None)])]
-    self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp2)
-    self.assertEqual (self.cache.deleted, {u'FOO-100': (table, row)})
+        # Calling initialized() for a record which wasn't inserted before must
+        # raise an exception
+        self.assertRaises(data.StateChangeError, self.cache.initialized,
+                           table, row)
 
-    # Cancel the delete operation; we should be again at the point of the last
-    # confirmation
-    self.cache.cancel ()
-    result = self.__orderTables (self.cache.dirtyTables ())
-    self.assertEqual (result, exp)
-    self.assertEqual (self.cache.deleted, {})
+        # Now delete the record. It will change it's state and shows up in the
+        # deletion queue
+        self.cache.deleteRecord(table, row)
+        exp2 = [(table, row, 'deleted', [(u'foo', 100), (u'gnue_id', None)])]
+        self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp2)
+        self.assertEqual(self.cache.deleted, {u'FOO-100': (table, row)})
 
-    # Make the changed record a clean record
-    self.cache.makeClean (table, row)
-    self.assertEqual (self.cache.dirtyTables (), {})
+        # Cancel the delete operation; we should be again at the point of the
+        # last confirmation
+        self.cache.cancel()
+        result = self.__orderTables(self.cache.dirtyTables())
+        self.assertEqual(result, exp)
+        self.assertEqual(self.cache.deleted, {})
 
-    # Delting a record and afterwards adding the same key points out a bug in
-    # appserver
-    self.cache.deleteRecord (u'frog', u'dummy')
-    self.assertRaises (data.DuplicateRecordError, self.cache.insertRecord,
-                       u'frog', u'dummy')
-    expected = [(u'frog', u'dummy', 'deleted', [(u'gnue_id', None)])]
-    self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), expected)
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {u'frog-dummy': (u'frog', u'dummy')})
+        # Make the changed record a clean record
+        self.cache.makeClean(table, row)
+        self.assertEqual(self.cache.dirtyTables(), {})
 
-    self.cache.cancel ()
-    self.assertEqual (self.cache.dirtyTables (), {})
-    self.assertEqual (self.cache.inserted, {})
-    self.assertEqual (self.cache.deleted, {})
+        # Delting a record and afterwards adding the same key points out a bug
+        # in appserver
+        self.cache.deleteRecord(u'frog', u'dummy')
+        self.assertRaises(data.DuplicateRecordError, self.cache.insertRecord,
+                           u'frog', u'dummy')
+        expected = [(u'frog', u'dummy', 'deleted', [(u'gnue_id', None)])]
+        self.assertEqual(self.__orderTables(self.cache.dirtyTables()), expected)
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted,
+                {u'frog-dummy': (u'frog', u'dummy')})
 
+        self.cache.cancel()
+        self.assertEqual(self.cache.dirtyTables(), {})
+        self.assertEqual(self.cache.inserted, {})
+        self.assertEqual(self.cache.deleted, {})
 
 
-  # ---------------------------------------------------------------------------
-  # Prepare the given cache-ditctionary
-  # ---------------------------------------------------------------------------
 
-  def __orderTables (self, tables):
-    """
-    Convert the given cache-dictionary into a comparable order. This function
-    creates a sequence of quadruples built from tablename, rowid, current state
-    of that row in the cache and an ordered sequence of (field, value) pairs.
-    This sequence is sorted as well as the sequence of field-values.
+    # -------------------------------------------------------------------------
+    # Prepare the given cache-ditctionary
+    # -------------------------------------------------------------------------
 
-    @param tables: cache-dictionary of the form 'dict [table] [row] [field]'
-    @return: ordered sequence [(table, row, state, [(field, value), ...]), ... ]
-    """
+    def __orderTables(self, tables):
+        """
+        Convert the given cache-dictionary into a comparable order. This
+        function creates a sequence of quadruples built from tablename, rowid,
+        current state of that row in the cache and an ordered sequence of
+        (field, value) pairs.  This sequence is sorted as well as the sequence
+        of field-values.
 
-    result = []
- 
-    for (table, rows) in tables.items ():
-      for (row, fields) in rows.items ():
-        fseq = fields.items ()
-        fseq.sort ()
+        @param tables: cache-dictionary of the form 'dict [table] [row] [field]'
+        @return: ordered sequence [(table, row, state, [(field, value), ...]),
+        ... ]
+        """
 
-        result.append ((table, row, self.cache.state (table, row), fseq))
+        result = []
 
-    result.sort ()
+        for (table, rows) in tables.items():
+            for (row, fields) in rows.items():
+                fseq = fields.items()
+                fseq.sort()
 
-    return result
+                result.append((table, row, self.cache.state(table, row), fseq))
 
+        result.sort()
 
+        return result
+
+
 # =============================================================================
 # TestCase for connection class
 # =============================================================================
 
-class ConnectionTestCase (unittest.TestCase):
-  """
-  TestCase for the connection class (= low level layer for sessions)
-  """
-
-  # ---------------------------------------------------------------------------
-  # Prepare the test case
-  # ---------------------------------------------------------------------------
-
-  def setUp (self):
+class ConnectionTestCase(unittest.TestCase):
     """
-    Create two seperate connections instances (so we can simulate two
-    concurrent sessions) and log into both (using 'gnue' as username and
-    password).
+    TestCase for the connection class (= low level layer for sessions)
     """
 
-    app = GClientApp.GClientApp (application = 'appserver',
-                                 defaults = geasConfiguration.ConfigOptions)
+    # -------------------------------------------------------------------------
+    # Prepare the test case
+    # -------------------------------------------------------------------------
 
-    # Fake the login to the default connection
-    c = app.connections.getConnection ('gnue')
-    c.parameters ['_username'] = 'gnue'
-    c.parameters ['_password'] = 'gnue'
+    def setUp(self):
+        """
+        Create two seperate connections instances (so we can simulate two
+        concurrent sessions) and log into both (using 'gnue' as username and
+        password).
+        """
 
-    conn = GConnections.GConnections (app.connections._location,
-                                      app.connections._loginHandler,
-                                      app.connections._loginOptions)
-    c2 = conn.getConnection ('gnue')
-    c2.parameters ['_username'] = 'gnue'
-    c2.parameters ['_password'] = 'gnue'
+        app = GClientApp.GClientApp(application = 'appserver',
+                                     defaults = geasConfiguration.ConfigOptions)
 
-    self.connection = data.connection (app.connections, 'gnue')
-    self.concurrent = data.connection (conn, 'gnue')
+        # Fake the login to the default connection
+        c = app.connections.getConnection('gnue')
+        c.parameters ['_username'] = 'gnue'
+        c.parameters ['_password'] = 'gnue'
 
-    self.remove = []
+        conn = GConnections.GConnections(app.connections._location,
+                                          app.connections._loginHandler,
+                                          app.connections._loginOptions)
+        c2 = conn.getConnection('gnue')
+        c2.parameters ['_username'] = 'gnue'
+        c2.parameters ['_password'] = 'gnue'
 
+        self.connection = data.connection(app.connections, 'gnue')
+        self.concurrent = data.connection(conn, 'gnue')
 
-  # ---------------------------------------------------------------------------
-  # Run some tests on the connection instance
-  # ---------------------------------------------------------------------------
+        self.remove = []
 
-  def testConnection (self):
-    """
-    Perform all tests
-    """
 
-    # Run an unordered query
-    content = {None: (u'address_person', None, None, [u'address_name'])}
-    rs = self.connection.query (content, None, None)
+    # -------------------------------------------------------------------------
+    # Run some tests on the connection instance
+    # -------------------------------------------------------------------------
 
-    self.assertEqual (len(rs), 4)
-    e = [u'James Tiberius Kirk', u'Spock', u'Leonard H. McCoy',
-         u'Pavel Andreievich Chekov']
-    e.sort ()
-    self.assertEqual (self.__rsToSeq (rs, [u'address_name'], True), e)
+    def testConnection(self):
+        """
+        Perform all tests
+        """
 
-    # Run an ordered query
-    content = {None: (u'address_person', None, None, [u'address_name'])}
-    rs = self.connection.query (content, None, [{'name': u'address_name'}])
+        # Run an unordered query
+        content = {None: (u'address_person', None, None, [u'address_name'])}
+        rs = self.connection.query(content, None, None)
 
-    self.assertEqual (len(rs), 4)
-    e = [u'James Tiberius Kirk', u'Leonard H. McCoy',
-         u'Pavel Andreievich Chekov', u'Spock']
-    self.assertEqual (self.__rsToSeq (rs, [u'address_name']), e)
+        self.assertEqual(len(rs), 4)
+        e = [u'James Tiberius Kirk', u'Spock', u'Leonard H. McCoy',
+             u'Pavel Andreievich Chekov']
+        e.sort()
+        self.assertEqual(self.__rsToSeq(rs, [u'address_name'], True), e)
 
-    # Run the same query again, and using a non-prefetched field
-    rs = self.connection.query (content, None, [{'name': u'address_name',
-                                                 'descending': True}])
-    result = []
-    for rec in rs:
-      result.append ((rec.getField (u'address_name'), rec.getField
-                     (u'address_zip')))
-    rs.close ()
+        # Run an ordered query
+        content = {None: (u'address_person', None, None, [u'address_name'])}
+        rs = self.connection.query(content, None, [{'name': u'address_name'}])
 
-    e = [(u'Spock', u'4711'),
-         (u'Pavel Andreievich Chekov', u'195251'),
-         (u'Leonard H. McCoy', u'39216'),
-         (u'James Tiberius Kirk', u'2002')]
+        self.assertEqual(len(rs), 4)
+        e = [u'James Tiberius Kirk', u'Leonard H. McCoy',
+             u'Pavel Andreievich Chekov', u'Spock']
+        self.assertEqual(self.__rsToSeq(rs, [u'address_name']), e)
 
-    self.assertEqual (result, e)
+        # Run the same query again, and using a non-prefetched field
+        rs = self.connection.query(content, None, [{'name': u'address_name',
+                                                     'descending': True}])
+        result = []
+        for rec in rs:
+            result.append((rec.getField(u'address_name'),
+                           rec.getField(u'address_zip')))
+        rs.close()
 
-    print "Simple condition ..."
-    # Run the query with a simple condition
-    cond = ['like', ['field', u'address_zip'], ['const', '%1']]
-    rs = self.connection.query (content, cond, [{'name': u'address_name'}])
+        e = [(u'Spock', u'4711'),
+             (u'Pavel Andreievich Chekov', u'195251'),
+             (u'Leonard H. McCoy', u'39216'),
+             (u'James Tiberius Kirk', u'2002')]
 
-    result = self.__rsToSeq (rs, [u'address_name'])
-    e = [u'Pavel Andreievich Chekov', u'Spock']
-    self.assertEqual (result, e)
+        self.assertEqual(result, e)
 
-    # -------------------------------------------------------------------------
-    # Checking dirty reads
+        # Run the query with a simple condition
+        cond = ['like', ['field', u'address_zip'], ['const', '%1']]
+        rs = self.connection.query(content, cond, [{'name': u'address_name'}])
 
-    print "Dirty reads ..."
-    (orgCrew, orgData) = self.__getCrewMembers ()
-    expected = [(u'James Tiberius Kirk', u'US'),
-                (u'Leonard H. McCoy', u'US'),
-                (u'Pavel Andreievich Chekov', u'RU'),
-                (u'Spock', None)]
+        result = self.__rsToSeq(rs, [u'address_name'])
+        e = [u'Pavel Andreievich Chekov', u'Spock']
+        self.assertEqual(result, e)
 
-    self.assertEqual (orgData, expected)
+        # ---------------------------------------------------------------------
+        # Checking dirty reads
 
-    # Now, Doc McCoy moves to Austria
-    austria = u'0000000000000000000000200000000F'
-    orgCrew [1].putField (u'address_country', austria)
-    
-    # Spock will leave (for the moment)
-    spocksId = orgCrew [-1].getField (u'gnue_id')
-    self.connection.deleteRecord (u'address_person', spocksId)
+        (orgCrew, orgData) = self.__get_crew_members()
+        expected = [(u'James Tiberius Kirk', u'US'),
+                    (u'Leonard H. McCoy', u'US'),
+                    (u'Pavel Andreievich Chekov', u'RU'),
+                    (u'Spock', None)]
 
-    # And a new crew member signs on
-    new = self.connection.insertRecord (u'address_person')
-    new.initialized ()
-    new.putField (u'address_name', u'Foobar')
-    new.putField (u'address_zip', u'6890')
-    new.putField (u'address_country', austria)
+        self.assertEqual(orgData, expected)
 
-    # So running the previous query again
-    (newCrew, newData) = self.__getCrewMembers ()
-    expected = [(u'Foobar', u'AT'),
-                (u'James Tiberius Kirk', u'US'),
-                (u'Leonard H. McCoy', u'AT'),
-                (u'Pavel Andreievich Chekov', u'RU')]
-    self.assertEqual (expected, newData)
+        # Now, Doc McCoy moves to Austria
+        austria = u'0000000000000000000000200000000F'
+        orgCrew[1].putField(u'address_country', austria)
 
-    # Now, there's another session doing the same request
-    (secCrew, secData) = self.__getCrewMembers (self.concurrent)
+        # Spock will leave (for the moment)
+        spocksId = orgCrew[-1].getField(u'gnue_id')
+        self.connection.deleteRecord(u'address_person', spocksId)
 
-    # Since the changes made before are not yet commited the second connection
-    # should still get the original result
-    self.assertEqual (orgData, secData)
+        # And a new crew member signs on
+        new = self.connection.insertRecord(u'address_person')
+        new.initialized()
+        new.putField(u'address_name', u'Foobar')
+        new.putField(u'address_zip', u'6890')
+        new.putField(u'address_country', austria)
 
-    # Cancelling the running atomic operation should also yield the former
-    # situation 
-    self.connection.cancelChanges ()
-    (newCrew, newData) = self.__getCrewMembers ()
+        # So running the previous query again
+        (newCrew, newData) = self.__get_crew_members()
 
-    self.assertEqual (orgData, newData)
+        expected = [(u'Foobar', u'AT'),
+                    (u'James Tiberius Kirk', u'US'),
+                    (u'Leonard H. McCoy', u'AT'),
+                    (u'Pavel Andreievich Chekov', u'RU')]
+        self.assertEqual(expected, newData)
 
-    # ---
-    # and again, Doc McCoy moves to Austria
-    austria = u'0000000000000000000000200000000F'
-    orgCrew [1].putField (u'address_country', austria)
-    
-    # Spock will leave (for the moment)
-    spocksId = orgCrew [-1].getField (u'gnue_id')
-    self.connection.deleteRecord (u'address_person', spocksId)
 
-    # And the captain becomes the senior of Checkov
-    orgCrew [-2].putField (u'address_senior',
-                           u'00000000000000000000000000001100')
+        # Now, there's another session doing the same request
+        (secCrew, secData) = self.__get_crew_members(self.concurrent)
 
-    # And a new crew member signs on
-    new = self.connection.insertRecord (u'address_person')
-    new.initialized ()
-    new.putField (u'address_name', u'Foobar')
-    new.putField (u'address_zip', u'6890')
-    new.putField (u'address_country', austria)
+        # Since the changes made before are not yet commited the second
+        # connection should still get the original result
+        self.assertEqual(orgData, secData)
 
-    oz = self.connection.insertRecord (u'address_country')
-    oz.initialized ()
-    oz.putField (u'address_code', u'OZ')
-    oz.putField (u'address_name', u'Oz')
+        # Cancelling the running atomic operation should also yield the former
+        # situation
+        self.connection.cancelChanges()
 
-    self.connection.confirmChanges ()
+        (newCrew, newData) = self.__get_crew_members()
 
-    # make some more changes
-    new.putField (u'address_name', u'buzzing the foobar')
-    new.putField (u'address_children', 2)
+        self.assertEqual(orgData, newData)
 
-    self.connection.deleteRecord (u'address_country', oz.getField (u'gnue_id'))
+        # ---
+        # and again, Doc McCoy moves to Austria
+        austria = u'0000000000000000000000200000000F'
+        orgCrew [1].putField(u'address_country', austria)
 
-    # change zip of James T. Kirk
-    orgCrew [0].putField (u'address_zip', u'0815')
+        # Spock will leave (for the moment)
+        spocksId = orgCrew [-1].getField(u'gnue_id')
+        self.connection.deleteRecord(u'address_person', spocksId)
 
-    # and now cancel all that changes
-    self.connection.cancelChanges ()
+        # And the captain becomes the senior of Checkov
+        orgCrew [-2].putField(u'address_senior',
+                               u'00000000000000000000000000001100')
 
-    (newCrew, newData) = self.__getCrewMembers ()
-    expected = [(u'Foobar', u'AT'),
-                (u'James Tiberius Kirk', u'US'),
-                (u'Leonard H. McCoy', u'AT'),
-                (u'Pavel Andreievich Chekov', u'RU')]
-    self.assertEqual (expected, newData)
+        # And a new crew member signs on
+        new = self.connection.insertRecord(u'address_person')
+        new.initialized()
+        new.putField(u'address_name', u'Foobar')
+        new.putField(u'address_zip', u'6890')
+        new.putField(u'address_country', austria)
 
-    # The address_country table should again contain the new country record
-    content   = {None: (u'address_country', None, None, [u'address_name'])}
-    condition = {u'address_code': u'OZ'}
-    resultSet = self.connection.query (content, condition, None)
-    self.assertEqual ([u'Oz'], self.__rsToSeq (resultSet, [u'address_name']))
+        oz = self.connection.insertRecord(u'address_country')
+        oz.initialized()
+        oz.putField(u'address_code', u'OZ')
+        oz.putField(u'address_name', u'Oz')
 
-    new.putField (u'address_country', oz.getField (u'gnue_id'))
+        self.connection.confirmChanges()
 
-    # Doing a commit here means storing all changes, but also shows if data.py
-    # does a proper sorting of insertions. This is because we've created the
-    # new person before the new country (which is in fact a master record for
-    # the person and theirfor must be added *before* the person).
-    self.connection.commit ()
+        # make some more changes
+        new.putField(u'address_name', u'buzzing the foobar')
+        new.putField(u'address_children', 2)
 
-    # Since the second session had no commit until now, no changes made by the
-    # first session should be visible at all.
-    (secCrew, secData) = self.__getCrewMembers (self.concurrent)
-    expected = [(u'James Tiberius Kirk', u'US'),
-                (u'Leonard H. McCoy', u'US'),
-                (u'Pavel Andreievich Chekov', u'RU'),
-                (u'Spock', None)]
-    self.assertEqual (expected, secData)
+        self.connection.deleteRecord(u'address_country',
+                oz.getField(u'gnue_id'))
 
-    # After closing the second session's transaction the query should now
-    # return all changes made by the first session
-    self.concurrent.rollback ()
+        # change zip of James T. Kirk
+        orgCrew [0].putField(u'address_zip', u'0815')
 
-    (secCrew, secData) = self.__getCrewMembers (self.concurrent)
-    expected = [(u'Foobar', u'OZ'),
-                (u'James Tiberius Kirk', u'US'),
-                (u'Leonard H. McCoy', u'AT'),
-                (u'Pavel Andreievich Chekov', u'RU')]
-    self.assertEqual (expected, secData)
+        # and now cancel all that changes
+        self.connection.cancelChanges()
 
-    self.connection.setConstraints (u'address_person',
-        {u'address_country': {u'address_country': True},
-         u'address_person':  {u'address_senior': True}})
+        (newCrew, newData) = self.__get_crew_members()
+        expected = [(u'Foobar', u'AT'),
+                    (u'James Tiberius Kirk', u'US'),
+                    (u'Leonard H. McCoy', u'AT'),
+                    (u'Pavel Andreievich Chekov', u'RU')]
+        self.assertEqual(expected, newData)
 
-    self.remove = [(u'address_person', new.getField (u'gnue_id')),
-                   (u'address_country', oz.getField (u'gnue_id'))]
+        # The address_country table should again contain the new country record
+        content   = {None: (u'address_country', None, None, [u'address_name'])}
+        condition = {u'address_code': u'OZ'}
+        resultSet = self.connection.query(content, condition, None)
+        self.assertEqual([u'Oz'], self.__rsToSeq(resultSet, [u'address_name']))
 
+        new.putField(u'address_country', oz.getField(u'gnue_id'))
 
+        # Doing a commit here means storing all changes, but also shows if
+        # data.py does a proper sorting of insertions. This is because we've
+        # created the new person before the new country (which is in fact a
+        # master record for the person and theirfor must be added *before* the
+        # person).
+        self.connection.commit()
 
-  # ---------------------------------------------------------------------------
-  # Restore to the initial situation in the test database
-  # ---------------------------------------------------------------------------
+        # Since the second session had no commit until now, no changes made by
+        # the first session should be visible at all.
+        (secCrew, secData) = self.__get_crew_members(self.concurrent)
+        expected = [(u'James Tiberius Kirk', u'US'),
+                    (u'Leonard H. McCoy', u'US'),
+                    (u'Pavel Andreievich Chekov', u'RU'),
+                    (u'Spock', None)]
+        self.assertEqual(expected, secData)
 
-  def tearDown (self):
-    """
-    Undo all changes made by the testcase
-    """
+        # After closing the second session's transaction the query should now
+        # return all changes made by the first session
+        self.concurrent.rollback()
 
-    self.connection.rollback ()
+        (secCrew, secData) = self.__get_crew_members(self.concurrent)
+        expected = [(u'Foobar', u'OZ'),
+                    (u'James Tiberius Kirk', u'US'),
+                    (u'Leonard H. McCoy', u'AT'),
+                    (u'Pavel Andreievich Chekov', u'RU')]
+        self.assertEqual(expected, secData)
 
-    # First we have to re-add the record for Spock
-    spock = self.connection.insertRecord (u'address_person')
-    spock.initialized ()
-    spock.putField (u'address_name', u'Spock')
-    spock.putField (u'address_street', u'Vulc Lane 1')
-    spock.putField (u'address_zip', u'4711')
-    spock.putField (u'address_city', u'Vulcane')
-    spock.putField (u'address_children', 0)
-    spock.putField (u'address_weight', 78.8)
-    spock.putField (u'address_born', u'2230-01-01')
-    spock.putField (u'address_meettime', u'6:30')
-    spock.putField (u'address_lastmeeting', u'2270-05-17 08:00')
-    spock.putField (u'address_human', False)
-    spock.putField (u'address_senior', u'00000000000000000000000000001100')
-    # This is a bit hackish cause we're changing the primary key
-    spock.putField (u'gnue_id', u'00000000000000000000000000001101')
+        self.connection.setConstraints(u'address_person',
+            {u'address_country': {u'address_country': True},
+             u'address_person':  {u'address_senior': True}})
 
-    # Reset the country for McCoy to the US
-    mccoy = self.connection.findRecord (u'address_person',
-                     u'00000000000000000000000000001102', [u'address_country'])
-    mccoy.putField (u'address_country', u'000000000000000000000020000000E3')
+        self.remove = [(u'address_person', new.getField(u'gnue_id')),
+                       (u'address_country', oz.getField(u'gnue_id'))]
 
-    # Reassign Spock as Checkov's senior
-    checkov = self.connection.findRecord (u'address_person',
-          u'00000000000000000000000000001103', [u'address_senior'])
-    checkov.putField (u'address_senior', u'00000000000000000000000000001101')
 
-    # And remove newly added records
-    for (table, row) in self.remove:
-      self.connection.deleteRecord (table, row)
 
-    self.connection.commit ()
+    # -------------------------------------------------------------------------
+    # Restore to the initial situation in the test database
+    # -------------------------------------------------------------------------
 
+    def tearDown(self):
+        """
+        Undo all changes made by the testcase
+        """
 
+        self.connection.rollback()
 
-  # ---------------------------------------------------------------------------
-  # Create a list of records and it's data for all crew members
-  # ---------------------------------------------------------------------------
+        # First we have to re-add the record for Spock
+        spock = self.connection.insertRecord(u'address_person')
+        spock.initialized()
+        spock.putField(u'address_name', u'Spock')
+        spock.putField(u'address_street', u'Vulc Lane 1')
+        spock.putField(u'address_zip', u'4711')
+        spock.putField(u'address_city', u'Vulcane')
+        spock.putField(u'address_children', 0)
+        spock.putField(u'address_weight', 78.8)
+        spock.putField(u'address_born', u'2230-01-01')
+        spock.putField(u'address_meettime', u'6:30')
+        spock.putField(u'address_lastmeeting', u'2270-05-17 08:00')
+        spock.putField(u'address_human', False)
+        spock.putField(u'address_senior', u'00000000000000000000000000001100')
+        # This is a bit hackish cause we're changing the primary key
+        spock.putField(u'gnue_id', u'00000000000000000000000000001101')
 
-  def __getCrewMembers (self, connection = None):
-    """
-    Create a list of records and it's data for all crew members
+        # Reset the country for McCoy to the US
+        mccoy = self.connection.findRecord(u'address_person',
+                         u'00000000000000000000000000001102',
+                         [u'address_country'])
+        mccoy.putField(u'address_country', u'000000000000000000000020000000E3')
 
-    @param connection: if given this connection instance will be used. It
-        defaults to 'self.connection'.
+        # Reassign Spock as Checkov's senior
+        checkov = self.connection.findRecord(u'address_person',
+              u'00000000000000000000000000001103', [u'address_senior'])
+        checkov.putField(u'address_senior', u'00000000000000000000000000001101')
 
-    @return: tuple (recordlist, datalist), where recordlist is a sequence of
-        data.record instances, and datalist is a sequence of tuples
-        (name, country-code), one per record found.
-    """
+        # And remove newly added records
+        for (table, row) in self.remove:
+            self.connection.deleteRecord(table, row)
 
-    if connection is None:
-      connection = self.connection
+        self.connection.commit()
 
-    # The following content definition drives 'address_person' as master table
-    # and joins 'address_country' in a left outer join, where 'address_name' is
-    # the onyle prefetched field for both tables. This forces data.py to do
-    # refetching for the joined table (cause we're accessing 'address_code').
-    content = {u't0': (u'address_person', None, None, [u'address_name']),
-               u't1': (u'address_country', u't0', u'address_country',
-                      [u'address_name'])}
 
-    sortOrder = [{'name': u't0.address_name'}]
-    resultSet = connection.query (content, None, sortOrder)
-    recList   = []
-    recData   = []
 
-    for rec in resultSet:
-      country = rec.getField (u'address_country')
-      if country is not None:
-        jRec  = connection.findRecord (u'address_country', country, [])
-        cCode = jRec.getField (u'address_code')
-      else:
-        cCode = None
+    # -------------------------------------------------------------------------
+    # Create a list of records and it's data for all crew members
+    # -------------------------------------------------------------------------
 
-      recData.append ((rec.getField (u'address_name'), cCode))
+    def __get_crew_members(self, connection=None):
+        """
+        Create a list of records and it's data for all crew members
 
-      recList.append (rec)
+        @param connection: if given this connection instance will be used. It
+            defaults to 'self.connection'.
 
-    resultSet.close ()
+        @return: tuple (recordlist, datalist), where recordlist is a sequence 
+            of data.record instances, and datalist is a sequence of tuples
+            (name, country-code), one per record found.
+        """
 
-    return (recList, recData)
+        if connection is None:
+            connection = self.connection
 
+        # The following content definition drives 'address_person' as master
+        # table and joins 'address_country' in a left outer join, where
+        # 'address_name' is the only prefetched field for both tables. This
+        # forces data.py to do refetching for the joined table (cause we're
+        # accessing 'address_code').
+        content = {u't0': (u'address_person', None, None, [u'address_name']),
+                   u't1': (u'address_country', u't0', u'address_country',
+                          [u'address_name'])}
 
-  # ---------------------------------------------------------------------------
-  # Convert a resultSet into a flat sequence
-  # ---------------------------------------------------------------------------
+        sortOrder = [{'name': u't0.address_name'}]
+        resultSet = connection.query(content, None, sortOrder)
+        recList   = []
+        recData   = []
 
-  def __rsToSeq (self, rs, fields, reorder = False):
-    """
-    Flatten a resultSet into a sequence of tuples holding the requested field
-    values.
+        for rec in resultSet:
+            country = rec.getField(u'address_country')
+            if country is not None:
+                jRec  = connection.findRecord(u'address_country', country, [])
+                cCode = jRec.getField(u'address_code')
+            else:
+                cCode = None
 
-    @param rs: the resultset to iterate
-    @param fields: sequence of fieldnames to extract
-    @param reorder: if True, the resulting sequence will be sorted
+            recData.append((rec.getField(u'address_name'), cCode))
 
-    @return: sequence of value-tuples, one per record. If only one field is
-        requested, the result is a sequence of field-values (without tuples)
-    """
+            recList.append(rec)
 
-    result = []
-    append = len (fields) == 1 and result.extend or result.append
+        resultSet.close()
 
-    for rec in rs:
-      append ([rec.getField (f) for f in fields])
+        return (recList, recData)
 
-    rs.close ()
 
-    if reorder:
-      result.sort ()
+    # -------------------------------------------------------------------------
+    # Convert a resultSet into a flat sequence
+    # -------------------------------------------------------------------------
 
-    return result
+    def __rsToSeq(self, rs, fields, reorder = False):
+        """
+        Flatten a resultSet into a sequence of tuples holding the requested
+        field values.
 
+        @param rs: the resultset to iterate
+        @param fields: sequence of fieldnames to extract
+        @param reorder: if True, the resulting sequence will be sorted
 
+        @return: sequence of value-tuples, one per record. If only one field is
+            requested, the result is a sequence of field-values (without tuples)
+        """
+
+        result = []
+        append = len(fields) == 1 and result.extend or result.append
+
+        for rec in rs:
+            append([rec.getField(f) for f in fields])
+
+        rs.close()
+
+        if reorder:
+            result.sort()
+
+        return result
+
+
 # =============================================================================
 # Main program
 # =============================================================================
 
 if __name__ == '__main__':
-  suite1 = unittest.makeSuite (CachingTestCase)
-  suite2 = unittest.makeSuite (ConnectionTestCase)
-  alltests = unittest.TestSuite ((suite1, suite2))
+    suite1 = unittest.makeSuite(CachingTestCase)
+    suite2 = unittest.makeSuite(ConnectionTestCase)
+    alltests = unittest.TestSuite((suite1, suite2))
 
-  unittest.TextTestRunner (verbosity = 2).run (alltests)
+    unittest.TextTestRunner(verbosity = 2).run(alltests)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.