[Zope-Checkins] CVS: Zope/lib/python/ZODB - FileStorage.py:1.98.2.3 ConflictResolution.py:1.13.6.2
Jeremy Hylton
jeremy@zope.com
Wed, 11 Dec 2002 11:30:46 -0500
Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv20407
Modified Files:
Tag: Zope-2_6-branch
FileStorage.py ConflictResolution.py
Log Message:
Backport several changes from the ZODB3-3_1-branch.
Fix subtle bug in restore().
Provide much simpler version of getSerial().
Add bogus __len__ to get tests work with Python 2.1.
load_class() returns None on error.
Add some extra tests that cover bugs fixed.
=== Zope/lib/python/ZODB/FileStorage.py 1.98.2.2 => 1.98.2.3 ===
--- Zope/lib/python/ZODB/FileStorage.py:1.98.2.2 Fri Nov 15 12:45:03 2002
+++ Zope/lib/python/ZODB/FileStorage.py Wed Dec 11 11:30:45 2002
@@ -568,31 +568,6 @@
if plen != z64: return read(U64(plen)), version, nv
return _loadBack(file, oid, read(8))[0], version, nv
- def getSerial(self, oid):
- self._lock_acquire()
- try:
- pos = self._index[oid]
- self._file.seek(pos)
- h = self._file.read(34)
- _oid = h[:8]
- if _oid != oid:
- raise CorruptedDataError, h
- vlen = unpack(">H", h[-2:])[0]
- if vlen:
- # If there is a version, find out its name and let
- # _load() do all the work. This is less efficient
- # than possible, because _load() will load the pickle
- # data. Being more efficient is too complicated.
- self._file.seek(24, 1) # skip plen, pnv, and pv
- version = self._file.read(vlen)
- pickledata, serial = self._load(oid, version,
- self._index, self._file)
- return serial
- return h[8:16]
- finally:
- self._lock_release()
-
-
def _load(self, oid, version, _index, file):
try:
pos = _index[oid]
@@ -808,7 +783,7 @@
try:
prev_pos = 0
if prev_txn is not None:
- prev_txn_pos = self._txn_find(prev_txn)
+ prev_txn_pos = self._txn_find(prev_txn, 0)
if prev_txn_pos:
prev_pos = self._data_find(prev_txn_pos, oid, data)
old = self._index_get(oid, 0)
@@ -1090,6 +1065,13 @@
else:
return '', ''
+ def getSerial(self, oid):
+ self._lock_acquire()
+ try:
+ return self._getSerial(oid, self._index[oid])
+ finally:
+ self._lock_release()
+
def _getSerial(self, oid, pos):
self._file.seek(pos)
h = self._file.read(16)
@@ -1223,12 +1205,12 @@
# Find the right transaction to undo and call _txn_undo_write().
tid = base64.decodestring(transaction_id + '\n')
assert len(tid) == 8
- tpos = self._txn_find(tid)
+ tpos = self._txn_find(tid, 1)
tindex = self._txn_undo_write(tpos, tid)
self._tindex.update(tindex)
return tindex.keys()
- def _txn_find(self, tid):
+ def _txn_find(self, tid, stop_at_pack):
pos = self._pos
# XXX Why 39? Only because undoLog() uses it as a boundary.
while pos > 39:
@@ -1239,9 +1221,10 @@
_tid = h[:8]
if _tid == tid:
return pos
- status = h[16] # get the c in 8s8sc
- if status == 'p' or _tid < self._packt:
- break
+ if stop_at_pack:
+ # If the status indicates the record is packed, stop.
+ if h[16] == 'p' or _tid < self._packt:
+ break
raise UndoError("Invalid transaction id")
def _txn_undo_write(self, tpos, tid):
@@ -2287,6 +2270,14 @@
if start:
self._skip_to_start(start)
self._stop = stop
+
+ def __len__(self):
+ # Define a bogus __len__() to make the iterator work
+ # with code like builtin list() and tuple() in Python 2.1.
+ # There's a lot of C code that expects a sequence to have
+ # an __len__() but can cope with any sort of mistake in its
+ # implementation. So just return 0.
+ return 0
def close(self):
file = self._file
=== Zope/lib/python/ZODB/ConflictResolution.py 1.13.6.1 => 1.13.6.2 ===
--- Zope/lib/python/ZODB/ConflictResolution.py:1.13.6.1 Tue Nov 12 16:13:58 2002
+++ Zope/lib/python/ZODB/ConflictResolution.py Wed Dec 11 11:30:45 2002
@@ -95,6 +95,8 @@
return 0
newstate = unpickler.load()
klass = load_class(class_tuple)
+ if klass is None:
+ return 0
inst = klass.__basicnew__()
try: