[Checkins] SVN: relstorage/ Updated the storage iterator code to be compatible with ZODB 3.9.

Shane Hathaway shane at hathawaymix.org
Wed Dec 17 18:43:54 EST 2008


Log message for revision 94158:
  Updated the storage iterator code to be compatible with ZODB 3.9.
  The RelStorage tests now pass with the shane-poll-invalidations branch
  of ZODB 3.9.
  

Changed:
  U   relstorage/branches/1.1/CHANGES.txt
  U   relstorage/branches/1.1/relstorage/relstorage.py
  U   relstorage/branches/1.1/relstorage/tests/reltestbase.py
  U   relstorage/trunk/CHANGES.txt

-=-
Modified: relstorage/branches/1.1/CHANGES.txt
===================================================================
--- relstorage/branches/1.1/CHANGES.txt	2008-12-17 23:29:38 UTC (rev 94157)
+++ relstorage/branches/1.1/CHANGES.txt	2008-12-17 23:43:54 UTC (rev 94158)
@@ -20,7 +20,11 @@
 - Optimized Oracle object retrieval by causing BLOBs to be sent inline
   when possible, based on a patch by Helge Tesdal.
 
+- Updated the storage iterator code to be compatible with ZODB 3.9.
+  The RelStorage tests now pass with the shane-poll-invalidations branch
+  of ZODB 3.9.
 
+
 RelStorage 1.1c1
 
 - Added optional memcache integration.  This is useful when the connection

Modified: relstorage/branches/1.1/relstorage/relstorage.py
===================================================================
--- relstorage/branches/1.1/relstorage/relstorage.py	2008-12-17 23:29:38 UTC (rev 94157)
+++ relstorage/branches/1.1/relstorage/relstorage.py	2008-12-17 23:43:54 UTC (rev 94158)
@@ -23,11 +23,20 @@
 import os
 import time
 import weakref
-from ZODB.utils import p64, u64, z64
-from ZODB.BaseStorage import BaseStorage
+from ZODB.utils import p64, u64
+from ZODB.BaseStorage import BaseStorage, TransactionRecord, DataRecord
 from ZODB import ConflictResolution, POSException
 from persistent.TimeStamp import TimeStamp
 
+try:
+    from ZODB.interfaces import StorageStopIteration
+except ImportError:
+    class StorageStopIteration(IndexError, StopIteration):
+        """A combination of StopIteration and IndexError to provide a
+        backwards-compatible exception.
+        """
+
+
 log = logging.getLogger("relstorage")
 
 # Set the RELSTORAGE_ABORT_EARLY environment variable when debugging
@@ -972,6 +981,9 @@
     def iterator(self):
         return self
 
+    def __iter__(self):
+        return self
+
     def __len__(self):
         return len(self._transactions)
 
@@ -982,29 +994,54 @@
     def next(self):
         if self._closed:
             raise IOError("TransactionIterator already closed")
+        if self._index >= len(self._transactions):
+            raise StorageStopIteration()
         params = self._transactions[self._index]
-        res = RecordIterator(self, *params)
+        res = RelStorageTransactionRecord(self, *params)
         self._index += 1
         return res
 
 
-class RecordIterator(object):
-    """Iterate over the objects in a transaction."""
+class RelStorageTransactionRecord(TransactionRecord):
+
     def __init__(self, trans_iter, tid_int, user, desc, ext, packed):
+        self._trans_iter = trans_iter
+        self._tid_int = tid_int
         self.tid = p64(tid_int)
         self.status = packed and 'p' or ' '
         self.user = user or ''
         self.description = desc or ''
         if ext:
-            self._extension = cPickle.loads(ext)
+            self.extension = cPickle.loads(ext)
         else:
-            self._extension = {}
+            self.extension = {}
 
-        cursor = trans_iter._cursor
-        adapter = trans_iter._adapter
+    # maintain compatibility with the old (ZODB 3.8 and below) name of
+    # the extension attribute.
+    def _ext_set(self, value):
+        self.extension = value
+    def _ext_get(self):
+        return self.extension
+    _extension = property(fset=_ext_set, fget=_ext_get)
+
+    def __iter__(self):
+        return RecordIterator(self)
+
+
+class RecordIterator(object):
+    """Iterate over the objects in a transaction."""
+    def __init__(self, record):
+        # record is a RelStorageTransactionRecord.
+        cursor = record._trans_iter._cursor
+        adapter = record._trans_iter._adapter
+        tid_int = record._tid_int
+        self.tid = record.tid
         self._records = list(adapter.iter_objects(cursor, tid_int))
         self._index = 0
 
+    def __iter__(self):
+        return self
+
     def __len__(self):
         return len(self._records)
 
@@ -1013,13 +1050,15 @@
         return self.next()
 
     def next(self):
+        if self._index >= len(self._records):
+            raise StorageStopIteration()
         params = self._records[self._index]
         res = Record(self.tid, *params)
         self._index += 1
         return res
 
 
-class Record(object):
+class Record(DataRecord):
     """An object state in a transaction"""
     version = ''
     data_txn = None

Modified: relstorage/branches/1.1/relstorage/tests/reltestbase.py
===================================================================
--- relstorage/branches/1.1/relstorage/tests/reltestbase.py	2008-12-17 23:29:38 UTC (rev 94157)
+++ relstorage/branches/1.1/relstorage/tests/reltestbase.py	2008-12-17 23:43:54 UTC (rev 94158)
@@ -13,8 +13,8 @@
 ##############################################################################
 """A foundation for relstorage adapter tests"""
 
+import itertools
 import time
-import unittest
 from relstorage.relstorage import RelStorage
 
 from ZODB.DB import DB
@@ -457,25 +457,33 @@
         eq = self.assertEqual
         iter1 = storage1.iterator()
         iter2 = storage2.iterator()
-        for txn1, txn2 in zip(iter1, iter2):
+        for txn1, txn2 in itertools.izip(iter1, iter2):
             eq(txn1.tid,         txn2.tid)
             eq(txn1.status,      txn2.status)
             eq(txn1.user,        txn2.user)
             eq(txn1.description, txn2.description)
-            eq(txn1._extension,  txn2._extension)
+
+            missing = object()
+            e1 = getattr(txn1, 'extension', missing)
+            if e1 is missing:
+                # old attribute name
+                e1 = txn1._extension
+            e2 = getattr(txn2, 'extension', missing)
+            if e2 is missing:
+                # old attribute name
+                e2 = txn2._extension
+            eq(e1, e2)
+
             recs1 = [(r.oid, r) for r in txn1]
             recs1.sort()
             recs2 = [(r.oid, r) for r in txn2]
             recs2.sort()
+            eq(len(recs1), len(recs2))
             for (oid1, rec1), (oid2, rec2) in zip(recs1, recs2):
                 eq(rec1.oid,     rec2.oid)
                 eq(rec1.tid,  rec2.tid)
                 eq(rec1.version, rec2.version)
                 eq(rec1.data,    rec2.data)
-            # Make sure there are no more records left in rec1 and rec2,
-            # meaning they were the same length.
-            self.assertRaises(IndexError, txn1.next)
-            self.assertRaises(IndexError, txn2.next)
         # Make sure ther are no more records left in txn1 and txn2, meaning
         # they were the same length
         self.assertRaises(IndexError, iter1.next)

Modified: relstorage/trunk/CHANGES.txt
===================================================================
--- relstorage/trunk/CHANGES.txt	2008-12-17 23:29:38 UTC (rev 94157)
+++ relstorage/trunk/CHANGES.txt	2008-12-17 23:43:54 UTC (rev 94158)
@@ -20,7 +20,11 @@
 - Optimized Oracle object retrieval by causing BLOBs to be sent inline
   when possible, based on a patch by Helge Tesdal.
 
+- Updated the storage iterator code to be compatible with ZODB 3.9.
+  The RelStorage tests now pass with the shane-poll-invalidations branch
+  of ZODB 3.9.
 
+
 RelStorage 1.1c1
 
 - Added optional memcache integration.  This is useful when the connection



More information about the Checkins mailing list