[Zodb-checkins] SVN: ZODB/branches/gocept-iteration/src/ZODB/ fixed broken version support on FileStorage.Record

Thomas Lotze tl at gocept.com
Wed Feb 13 10:58:03 EST 2008


Log message for revision 83797:
  fixed broken version support on FileStorage.Record
  

Changed:
  U   ZODB/branches/gocept-iteration/src/ZODB/BaseStorage.py
  U   ZODB/branches/gocept-iteration/src/ZODB/FileStorage/FileStorage.py
  U   ZODB/branches/gocept-iteration/src/ZODB/tests/testFileStorage.py

-=-
Modified: ZODB/branches/gocept-iteration/src/ZODB/BaseStorage.py
===================================================================
--- ZODB/branches/gocept-iteration/src/ZODB/BaseStorage.py	2008-02-13 13:53:55 UTC (rev 83796)
+++ ZODB/branches/gocept-iteration/src/ZODB/BaseStorage.py	2008-02-13 15:58:03 UTC (rev 83797)
@@ -21,14 +21,18 @@
 import logging
 from struct import pack as _structpack, unpack as _structunpack
 
+import zope.interface
+
 from persistent.TimeStamp import TimeStamp
 
+import ZODB.interfaces
 from ZODB import POSException
 from ZODB.utils import z64, oid_repr
 from ZODB.UndoLogCompatible import UndoLogCompatible
 
 log = logging.getLogger("ZODB.BaseStorage")
 
+
 class BaseStorage(UndoLogCompatible):
     """Base class that supports storage implementations.
 
@@ -338,7 +342,7 @@
             if verbose:
                 print oid_repr(oid), r.version, len(r.data)
             if restoring:
-                dest.restore(oid, r.tid, r.data, '',
+                dest.restore(oid, r.tid, r.data, r.version,
                              r.data_txn, transaction)
             else:
                 pre = preget(oid, None)
@@ -350,8 +354,28 @@
 
     fiter.close()
 
-class TransactionRecord:
+
+class TransactionRecord(object):
     """Abstract base class for iterator protocol"""
 
-class DataRecord:
+    zope.interface.implements(ZODB.interfaces.IStorageTransactionInformation)
+
+    def __init__(self, tid, status, user, description, extension):
+        self.tid = tid
+        self.status = status
+        self.user = user
+        self.description = description
+        self.extension = extension
+
+
+class DataRecord(object):
     """Abstract base class for iterator protocol"""
+
+    zope.interface.implements(ZODB.interfaces.IStorageRecordInformation)
+
+    def __init__(self, oid, tid, data, version, prev):
+        self.oid = oid
+        self.tid = tid
+        self.data = data
+        self.version = version
+        self.data_txn = prev

Modified: ZODB/branches/gocept-iteration/src/ZODB/FileStorage/FileStorage.py
===================================================================
--- ZODB/branches/gocept-iteration/src/ZODB/FileStorage/FileStorage.py	2008-02-13 13:53:55 UTC (rev 83796)
+++ ZODB/branches/gocept-iteration/src/ZODB/FileStorage/FileStorage.py	2008-02-13 15:58:03 UTC (rev 83797)
@@ -1526,7 +1526,10 @@
         __index=self.__index
         while i > __index:
             __index=__index+1
-            self.__current=self.next(__index)
+            try:
+                self.__current=self.next()
+            except StopIteration:
+                raise IndexError(i)
 
         self.__index=__index
         return self.__current
@@ -1602,7 +1605,7 @@
                     panic("%s has inconsistent transaction length at %s "
                           "(%s != %s)", file.name, pos, u64(rtl), u64(stl))
 
-    def next(self, index=0):
+    def next(self):
         if self._file is None:
             # A closed iterator.  Is IOError the best we can do?  For
             # now, mimic a read on a closed file.
@@ -1625,11 +1628,11 @@
             self._ltid = h.tid
 
             if self._stop is not None and h.tid > self._stop:
-                raise IndexError(index)
+                raise StopIteration
 
             if h.status == "c":
                 # Assume we've hit the last, in-progress transaction
-                raise IndexError(index)
+                raise StopIteration
 
             if pos + h.tlen + 8 > self._file_size:
                 # Hm, the data were truncated or the checkpoint flag wasn't
@@ -1693,16 +1696,15 @@
 
             return result
 
-        raise IndexError(index)
+        raise StopIteration
 
+
 class RecordIterator(Iterator, BaseStorage.TransactionRecord,
                      FileStorageFormatter):
     """Iterate over the transactions in a FileStorage file."""
     def __init__(self, tid, status, user, desc, ext, pos, tend, file, tpos):
-        self.tid = tid
-        self.status = status
-        self.user = user
-        self.description = desc
+        BaseStorage.TransactionRecord.__init__(
+            self, tid, status, user, desc, ext)
         self._extension = ext
         self._pos = pos
         self._tend = tend
@@ -1743,15 +1745,14 @@
 
         raise IndexError(index)
 
+
 class Record(BaseStorage.DataRecord):
-    """An abstract database record."""
+
     def __init__(self, oid, tid, data, prev, pos):
-        self.oid = oid
-        self.tid = tid
-        self.data = data
-        self.data_txn = prev
+        super(Record, self).__init__(oid, tid, data, '', prev)
         self.pos = pos
 
+
 class UndoSearch:
 
     def __init__(self, file, pos, first, last, filter=None):

Modified: ZODB/branches/gocept-iteration/src/ZODB/tests/testFileStorage.py
===================================================================
--- ZODB/branches/gocept-iteration/src/ZODB/tests/testFileStorage.py	2008-02-13 13:53:55 UTC (rev 83796)
+++ ZODB/branches/gocept-iteration/src/ZODB/tests/testFileStorage.py	2008-02-13 15:58:03 UTC (rev 83797)
@@ -308,6 +308,7 @@
             else:
                 self.assertNotEqual(next_oid, None)
 
+
 class FileStorageRecoveryTest(
     StorageTestBase.StorageTestBase,
     RecoveryStorage.RecoveryStorage,
@@ -326,6 +327,40 @@
     def new_dest(self):
         return ZODB.FileStorage.FileStorage('Dest.fs')
 
+
+class FileStorageNoRestore(ZODB.FileStorage.FileStorage):
+
+    @property
+    def restore(self):
+        raise Exception
+
+
+class FileStorageNoRestoreRecoveryTest(
+    StorageTestBase.StorageTestBase,
+    RecoveryStorage.RecoveryStorage,
+    ):
+    # This test actually verifies a code path of
+    # BaseStorage.copyTransactionsFrom. For simplicity of implementation, we
+    # use a FileStorage deprived of its restore method.
+
+    def setUp(self):
+        self._storage = FileStorageNoRestore("Source.fs", create=True)
+        self._dst = FileStorageNoRestore("Dest.fs", create=True)
+
+    def tearDown(self):
+        self._storage.close()
+        self._dst.close()
+        self._storage.cleanup()
+        self._dst.cleanup()
+
+    def new_dest(self):
+        return FileStorageNoRestore('Dest.fs')
+
+    def checkRestoreAcrossPack(self):
+        # Skip this check as it calls restore directly.
+        pass
+
+
 class SlowFileStorageTest(BaseFileStorageTests):
 
     level = 2
@@ -492,7 +527,8 @@
 
     suite = unittest.TestSuite()
     for klass in [FileStorageTests, Corruption.FileStorageCorruptTests,
-                  FileStorageRecoveryTest, SlowFileStorageTest]:
+                  FileStorageRecoveryTest, FileStorageNoRestoreRecoveryTest,
+                  SlowFileStorageTest]:
         suite.addTest(unittest.makeSuite(klass, "check"))
     suite.addTest(doctest.DocTestSuite(setUp=ZODB.tests.util.setUp,
                                        tearDown=ZODB.tests.util.tearDown))



More information about the Zodb-checkins mailing list