Commit 0eabedc1 authored by Jim Fulton's avatar Jim Fulton

Bug Fixed

  Conflict resolution failed when state included cross-database
  persistent references with classes that couldn't be imported.
parent 1aa46816
...@@ -2,6 +2,15 @@ ...@@ -2,6 +2,15 @@
Change History Change History
================ ================
3.10.5 (2011-11-19)
===================
Bugs Fixed
----------
- Conflict resolution failed when state included cross-database
persistent references with classes that couldn't be imported.
3.10.4 (2011-11-17) 3.10.4 (2011-11-17)
=================== ===================
......
...@@ -140,7 +140,10 @@ class PersistentReference(object): ...@@ -140,7 +140,10 @@ class PersistentReference(object):
# or persistent weakref: (oid, database_name) # or persistent weakref: (oid, database_name)
# else it is a weakref: reference_type # else it is a weakref: reference_type
if reference_type == 'm': if reference_type == 'm':
self.database_name, self.oid, _ = data[1] self.database_name, self.oid, klass = data[1]
if isinstance(klass, BadClass):
# see above wrt BadClass
data[1] = self.database_name, self.oid, klass.args
elif reference_type == 'n': elif reference_type == 'n':
self.database_name, self.oid = data[1] self.database_name, self.oid = data[1]
elif reference_type == 'w': elif reference_type == 'w':
......
...@@ -237,8 +237,60 @@ Bwahaha: ...@@ -237,8 +237,60 @@ Bwahaha:
""" """
def resolve_even_when_xdb_referenced_classes_are_absent():
"""Cross-database persistent refs!
>>> class P(persistent.Persistent):
... pass
>>> databases = {}
>>> db = ZODB.DB('t.fs', databases=databases, database_name='')
>>> _ = ZODB.DB('o.fs', databases=databases, database_name='o')
>>> storage = db.storage
>>> conn = db.open()
>>> conn.root.x = Resolveable()
>>> transaction.commit()
>>> oid = conn.root.x._p_oid
>>> serial = conn.root.x._p_serial
>>> p = P(); conn.get_connection('o').add(p)
>>> conn.root.x.a = p
>>> transaction.commit()
>>> aid = conn.root.x.a._p_oid
>>> serial1 = conn.root.x._p_serial
>>> del conn.root.x.a
>>> p = P(); conn.get_connection('o').add(p)
>>> conn.root.x.b = p
>>> transaction.commit()
>>> serial2 = conn.root.x._p_serial
>>> del p
Bwahaha:
>>> P_aside = P
>>> del P
Now, even though we can't import P, we can still resolve the conflict:
>>> p = storage.tryToResolveConflict(
... oid, serial1, serial, storage.loadSerial(oid, serial2))
And load the pickle:
>>> conn2 = db.open()
>>> conn2o = conn2.get_connection('o')
>>> P = P_aside
>>> p = conn2._reader.getState(p)
>>> sorted(p), p['a'] is conn2o.get(aid), p['b'] is conn2.root.x.b
(['a', 'b'], True, True)
>>> isinstance(p['a'], P) and isinstance(p['b'], P)
True
>>> db.close()
"""
def test_suite(): def test_suite():
return unittest.TestSuite([ return 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