Commit 91c7c629 authored by Jeremy Hylton's avatar Jeremy Hylton

Better fix for George Bailey events.

Also, add sanity checks in _getVersion() and _getSerial().
parent 0dc7ce85
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
# may have a back pointer to a version record or to a non-version # may have a back pointer to a version record or to a non-version
# record. # record.
# #
__version__='$Revision: 1.111 $'[11:-2] __version__='$Revision: 1.112 $'[11:-2]
import base64 import base64
from cPickle import Pickler, Unpickler, loads from cPickle import Pickler, Unpickler, loads
...@@ -1045,19 +1045,20 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -1045,19 +1045,20 @@ class FileStorage(BaseStorage.BaseStorage,
def _getVersion(self, oid, pos): def _getVersion(self, oid, pos):
self._file.seek(pos) self._file.seek(pos)
read=self._file.read h = self._file.read(DATA_HDR_LEN)
h=read(DATA_HDR_LEN) doid, serial, sprev, stloc, vlen, splen = unpack(DATA_HDR, h)
doid,serial,sprev,stloc,vlen,splen = unpack(DATA_HDR, h)
assert doid == oid assert doid == oid
if vlen: if vlen:
h=read(16) h = self._file.read(16)
return read(vlen), h[:8] return self._file.read(vlen), h[:8]
else: else:
return '','' return '', ''
def _getSerial(self, oid, pos): def _getSerial(self, oid, pos):
self._file.seek(pos+8) self._file.seek(pos)
return self._file.read(8) h = self._file.read(16)
assert oid == h[:8]
return h[8:]
def _transactionalUndoRecord(self, oid, pos, serial, pre, version): def _transactionalUndoRecord(self, oid, pos, serial, pre, version):
"""Get the indo information for a data record """Get the indo information for a data record
...@@ -1069,6 +1070,8 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -1069,6 +1070,8 @@ class FileStorage(BaseStorage.BaseStorage,
""" """
copy=1 # Can we just copy a data pointer copy=1 # Can we just copy a data pointer
# First check if it is possible to undo this record.
tpos=self._tindex.get(oid, 0) tpos=self._tindex.get(oid, 0)
ipos=self._index.get(oid, 0) ipos=self._index.get(oid, 0)
tipos=tpos or ipos tipos=tpos or ipos
...@@ -1103,10 +1106,13 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -1103,10 +1106,13 @@ class FileStorage(BaseStorage.BaseStorage,
# LoadBack gave us a key error. Bail. # LoadBack gave us a key error. Bail.
raise UndoError raise UndoError
if pre: # Return the data that should be written in the undo record.
version, snv = self._getVersion(oid, pre) if not pre:
else: # There is no previous revision, because the object creation
version, snv = '', '' # is being undone.
return '', 0, '', '', ipos
version, snv = self._getVersion(oid, pre)
if copy: if copy:
# we can just copy our previous-record pointer forward # we can just copy our previous-record pointer forward
return '', pre, version, snv, ipos return '', pre, version, snv, ipos
...@@ -1265,7 +1271,7 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -1265,7 +1271,7 @@ class FileStorage(BaseStorage.BaseStorage,
tindex[oid] = here tindex[oid] = here
here += odlen here += odlen
pos=pos+dlen pos += dlen
if pos > tend: if pos > tend:
raise UndoError, 'non-undoable transaction' raise UndoError, 'non-undoable transaction'
...@@ -2142,6 +2148,7 @@ def _loadBack_impl(file, oid, back): ...@@ -2142,6 +2148,7 @@ def _loadBack_impl(file, oid, back):
while 1: while 1:
old = U64(back) old = U64(back)
if not old: if not old:
# If the backpointer is 0, the object does not currently exist.
raise POSKeyError(oid) raise POSKeyError(oid)
file.seek(old) file.seek(old)
h = file.read(DATA_HDR_LEN) h = file.read(DATA_HDR_LEN)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment