Commit 363be546 authored by Patrick Strawderman's avatar Patrick Strawderman

Bug fix: DemoStorage.loadBefore returned invalid data when

passed a tid older than anything in changes but newer than
anything in base.
parent 6c94c097
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
Bugs Fixed Bugs Fixed
---------- ----------
- DemoStorage.loadBefore sometimes returned invalid data which
would trigger AssertionErrors in ZODB.Connection.
- History support was broken when using stprages that work with ZODB - History support was broken when using stprages that work with ZODB
3.8 and 3.9. 3.8 and 3.9.
......
...@@ -153,11 +153,18 @@ class DemoStorage(object): ...@@ -153,11 +153,18 @@ class DemoStorage(object):
# The oid *was* in the changes, but there aren't any # The oid *was* in the changes, but there aren't any
# earlier records. Maybe there are in the base. # earlier records. Maybe there are in the base.
try: try:
return self.base.loadBefore(oid, tid) result = self.base.loadBefore(oid, tid)
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
# The oid isn't in the base, so None will be the right result # The oid isn't in the base, so None will be the right result
pass pass
else:
if result and not result[-1]:
end_tid = None
t = self.changes.load(oid)
while t:
end_tid = t[1]
t = self.changes.loadBefore(oid, end_tid)
result = result[:2] + (end_tid,)
return result return result
def loadBlob(self, oid, serial): def loadBlob(self, oid, serial):
......
...@@ -171,6 +171,53 @@ def blob_pos_key_error_with_non_blob_base(): ...@@ -171,6 +171,53 @@ def blob_pos_key_error_with_non_blob_base():
""" """
def load_before_base_storage_current():
"""
Here we'll exercise that DemoStorage's loadBefore method works
properly when deferring to a record that is current in the
base storage.
>>> import transaction
>>> import ZODB.DB
>>> import ZODB.DemoStorage
>>> import ZODB.MappingStorage
>>> import ZODB.utils
>>> base = ZODB.MappingStorage.MappingStorage()
>>> basedb = ZODB.DB(base)
>>> conn = basedb.open()
>>> conn.root()['foo'] = 'bar'
>>> transaction.commit()
>>> conn.close()
>>> storage = ZODB.DemoStorage.DemoStorage(base=base)
>>> db = ZODB.DB(storage)
>>> conn = db.open()
>>> conn.root()['foo'] = 'baz'
>>> transaction.commit()
>>> oid = ZODB.utils.z64
>>> base_current = storage.base.load(oid)
>>> tid = ZODB.utils.p64(ZODB.utils.u64(base_current[1]) + 1)
>>> base_record = storage.base.loadBefore(oid, tid)
>>> base_record[-1] is None
True
>>> base_current == base_record[:2]
True
>>> t = storage.loadBefore(oid, tid)
The data and tid are the values from the base storage, but the
next tid is from changes.
>>> t[:2] == base_record[:2]
True
>>> t[-1] == storage.changes.load(oid)[1]
True
>>> conn.close()
>>> db.close()
>>> base.close()
"""
def test_suite(): def test_suite():
suite = unittest.TestSuite(( suite = unittest.TestSuite((
......
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