Commit c6ebcedf authored by Barry Warsaw's avatar Barry Warsaw

Pass the final crop of ZEO and restore tests. Changes include:

_dorestore(): Adopt the FileStorage semantics for when the transaction
pointed to by prev_txn does not exist.  This can happen if we're
restoring to a storage where that transaction has been packed away.
In that case, treat prev_txn as a hint and ignore it. :)

_TransactionsIterator.__len__(): Give this a dummy (and lying)
implementation which is just good enough for Python 2.1.3 support.
parent a675bdb0
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"""Berkeley storage with full undo and versioning support. """Berkeley storage with full undo and versioning support.
""" """
__version__ = '$Revision: 1.60 $'.split()[-2:][0] __version__ = '$Revision: 1.61 $'.split()[-2:][0]
import time import time
import cPickle as pickle import cPickle as pickle
...@@ -575,20 +575,28 @@ class Full(BerkeleyBase, ConflictResolvingStorage): ...@@ -575,20 +575,28 @@ class Full(BerkeleyBase, ConflictResolvingStorage):
# Get the metadata for the previous revision, so that we can dig out # Get the metadata for the previous revision, so that we can dig out
# the non-version revid, but only if there /is/ a previous revision # the non-version revid, but only if there /is/ a previous revision
if prevrevid <> ZERO: if prevrevid <> ZERO:
ovid, onvrevid = unpack( try:
'>8s8s', self._metadata[oid+prevrevid][:16]) ovid, onvrevid = unpack(
if ovid == ZERO: '>8s8s', self._metadata[oid+prevrevid][:16])
# The last revision of this object was made on the except KeyError:
# non-version, we don't care where the current change is # prev_txn is just a hint. If the transaction it points to
# made. But if we're storing this change on a version then # does not exist, perhaps because it's been packed away, just
# the non-version revid will be the previous revid # ignore it. Also, check to see if the data matches. If
if version: # not...
nvrevid = prevrevid prevrevid = ZERO
else: else:
# We're making another change to this object on this version. if ovid == ZERO:
# The non-version revid is the same as for the previous # The last revision of this object was made on the
# revision of the object. # non-version, we don't care where the current change is
nvrevid = onvrevid # made. But if we're storing this change on a version
# then the non-version revid will be the previous revid
if version:
nvrevid = prevrevid
else:
# We're making another change to this object on this
# version. The non-version revid is the same as for the
# previous revision of the object.
nvrevid = onvrevid
# Check for George Bailey Events # Check for George Bailey Events
if data is None: if data is None:
lrevid = DNE lrevid = DNE
...@@ -629,8 +637,14 @@ class Full(BerkeleyBase, ConflictResolvingStorage): ...@@ -629,8 +637,14 @@ class Full(BerkeleyBase, ConflictResolvingStorage):
# - data can be None, which indicates a George Bailey object # - data can be None, which indicates a George Bailey object
# (i.e. one who's creation has been transactionally undone). # (i.e. one who's creation has been transactionally undone).
# #
# If prev_txn is not None, it should contain the same data as # prev_txn is a backpointer. In the original database, it's possible
# the argument data. If it does, write a backpointer to it. # that the data was actually living in a previous transaction. This
# can happen for transactional undo and other operations, and is used
# as a space saving optimization. Under some circumstances the
# prev_txn may not actually exist in the target database (i.e. self)
# for example, if it's been packed away. In that case, the prev_txn
# should be considered just a hint, and is ignored if the transaction
# doesn't exist.
if transaction is not self._transaction: if transaction is not self._transaction:
raise POSException.StorageTransactionError(self, transaction) raise POSException.StorageTransactionError(self, transaction)
self._lock_acquire() self._lock_acquire()
...@@ -1760,6 +1774,11 @@ class _TransactionsIterator(_GetItemBase): ...@@ -1760,6 +1774,11 @@ class _TransactionsIterator(_GetItemBase):
self._closed = False self._closed = False
self._first = True self._first = True
def __len__(self):
# This is a lie. It's here only for Python 2.1 support for
# list()-ifying these objects.
return 0
def next(self): def next(self):
"""Return the ith item in the sequence of transaction data. """Return the ith item in the sequence of transaction data.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"""Berkeley storage with full undo and versioning support. """Berkeley storage with full undo and versioning support.
""" """
__version__ = '$Revision: 1.60 $'.split()[-2:][0] __version__ = '$Revision: 1.61 $'.split()[-2:][0]
import time import time
import cPickle as pickle import cPickle as pickle
...@@ -575,20 +575,28 @@ class Full(BerkeleyBase, ConflictResolvingStorage): ...@@ -575,20 +575,28 @@ class Full(BerkeleyBase, ConflictResolvingStorage):
# Get the metadata for the previous revision, so that we can dig out # Get the metadata for the previous revision, so that we can dig out
# the non-version revid, but only if there /is/ a previous revision # the non-version revid, but only if there /is/ a previous revision
if prevrevid <> ZERO: if prevrevid <> ZERO:
ovid, onvrevid = unpack( try:
'>8s8s', self._metadata[oid+prevrevid][:16]) ovid, onvrevid = unpack(
if ovid == ZERO: '>8s8s', self._metadata[oid+prevrevid][:16])
# The last revision of this object was made on the except KeyError:
# non-version, we don't care where the current change is # prev_txn is just a hint. If the transaction it points to
# made. But if we're storing this change on a version then # does not exist, perhaps because it's been packed away, just
# the non-version revid will be the previous revid # ignore it. Also, check to see if the data matches. If
if version: # not...
nvrevid = prevrevid prevrevid = ZERO
else: else:
# We're making another change to this object on this version. if ovid == ZERO:
# The non-version revid is the same as for the previous # The last revision of this object was made on the
# revision of the object. # non-version, we don't care where the current change is
nvrevid = onvrevid # made. But if we're storing this change on a version
# then the non-version revid will be the previous revid
if version:
nvrevid = prevrevid
else:
# We're making another change to this object on this
# version. The non-version revid is the same as for the
# previous revision of the object.
nvrevid = onvrevid
# Check for George Bailey Events # Check for George Bailey Events
if data is None: if data is None:
lrevid = DNE lrevid = DNE
...@@ -629,8 +637,14 @@ class Full(BerkeleyBase, ConflictResolvingStorage): ...@@ -629,8 +637,14 @@ class Full(BerkeleyBase, ConflictResolvingStorage):
# - data can be None, which indicates a George Bailey object # - data can be None, which indicates a George Bailey object
# (i.e. one who's creation has been transactionally undone). # (i.e. one who's creation has been transactionally undone).
# #
# If prev_txn is not None, it should contain the same data as # prev_txn is a backpointer. In the original database, it's possible
# the argument data. If it does, write a backpointer to it. # that the data was actually living in a previous transaction. This
# can happen for transactional undo and other operations, and is used
# as a space saving optimization. Under some circumstances the
# prev_txn may not actually exist in the target database (i.e. self)
# for example, if it's been packed away. In that case, the prev_txn
# should be considered just a hint, and is ignored if the transaction
# doesn't exist.
if transaction is not self._transaction: if transaction is not self._transaction:
raise POSException.StorageTransactionError(self, transaction) raise POSException.StorageTransactionError(self, transaction)
self._lock_acquire() self._lock_acquire()
...@@ -1760,6 +1774,11 @@ class _TransactionsIterator(_GetItemBase): ...@@ -1760,6 +1774,11 @@ class _TransactionsIterator(_GetItemBase):
self._closed = False self._closed = False
self._first = True self._first = True
def __len__(self):
# This is a lie. It's here only for Python 2.1 support for
# list()-ifying these objects.
return 0
def next(self): def next(self):
"""Return the ith item in the sequence of transaction data. """Return the ith item in the sequence of transaction data.
......
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