[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