[Zodb-checkins] SVN: ZODB/trunk/src/ZODB/ Fixed the basic tests to open the second db correctly.

Jim Fulton jim at zope.com
Thu Jun 16 06:56:55 EDT 2005


Log message for revision 30810:
  Fixed the basic tests to open the second db correctly.
  Secondary connections always need to be made from an existing
  connection.
  
  Added check to make sure we don't get references across incompatible
  connections.
  

Changed:
  U   ZODB/trunk/src/ZODB/cross-database-references.txt
  U   ZODB/trunk/src/ZODB/serialize.py
  U   ZODB/trunk/src/ZODB/tests/testcrossdatabasereferences.py

-=-
Modified: ZODB/trunk/src/ZODB/cross-database-references.txt
===================================================================
--- ZODB/trunk/src/ZODB/cross-database-references.txt	2005-06-16 10:56:53 UTC (rev 30809)
+++ ZODB/trunk/src/ZODB/cross-database-references.txt	2005-06-16 10:56:55 UTC (rev 30810)
@@ -19,11 +19,17 @@
     >>> conn1.root()['p'] = p1
     >>> tm.commit()
 
+First, we get a connection to the second database.  We get the second
+connection using the first connection's `get_connextion` method.  This
+is important.  When using multiple databases, we need to make sure we
+use a consistent set of connections so that the objects in the
+connection caches are connected in a consistent manner.
+
+    >>> conn2 = conn1.get_connection('2')
+
 Now, we'll create a second persistent object in the second database.
 We'll have a reference to the first object:
 
-    >>> tm = transaction.TransactionManager()
-    >>> conn2 = db2.open(transaction_manager=tm)
     >>> p2 = MyClass()
     >>> conn2.root()['p'] = p2
     >>> p2.p1 = p1

Modified: ZODB/trunk/src/ZODB/serialize.py
===================================================================
--- ZODB/trunk/src/ZODB/serialize.py	2005-06-16 10:56:53 UTC (rev 30809)
+++ ZODB/trunk/src/ZODB/serialize.py	2005-06-16 10:56:55 UTC (rev 30810)
@@ -337,6 +337,14 @@
                     "database connection"
                     )
 
+            if self._jar.get_connection(database_name) is not obj._p_jar:
+                raise InvalidObjectReference(
+                    "Attempt to store a reference to an object from "
+                    "a separate onnection to the same database or "
+                    "multidatabase"
+                    )
+                
+
         klass = type(obj)
         if hasattr(klass, '__getnewargs__'):
             # We don't want to save newargs in object refs.

Modified: ZODB/trunk/src/ZODB/tests/testcrossdatabasereferences.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testcrossdatabasereferences.py	2005-06-16 10:56:53 UTC (rev 30809)
+++ ZODB/trunk/src/ZODB/tests/testcrossdatabasereferences.py	2005-06-16 10:56:55 UTC (rev 30810)
@@ -26,6 +26,59 @@
     def __getnewargs__(self):
         return ()
 
+def test_must_use_consistent_connections():
+    """
+
+It's important to use consistent connections.  References to to
+separate connections to the ssme database or multi-database won't
+work.
+
+For example, it's tempting to open a second database using the
+database open function, but this doesn't work:
+
+    >>> import ZODB.tests.util, transaction, persistent
+    >>> databases = {}
+    >>> db1 = ZODB.tests.util.DB(databases=databases, database_name='1')
+    >>> db2 = ZODB.tests.util.DB(databases=databases, database_name='2')
+
+    >>> tm = transaction.TransactionManager()
+    >>> conn1 = db1.open(transaction_manager=tm)
+    >>> p1 = MyClass()
+    >>> conn1.root()['p'] = p1
+    >>> tm.commit()
+
+    >>> conn2 = db2.open(transaction_manager=tm)
+
+    >>> p2 = MyClass()
+    >>> conn2.root()['p'] = p2
+    >>> p2.p1 = p1
+    >>> tm.commit() # doctest: +NORMALIZE_WHITESPACE
+    Traceback (most recent call last):
+    ...
+    InvalidObjectReference: Attempt to store a reference to an object
+    from a separate onnection to the same database or multidatabase
+
+    >>> tm.abort()
+
+Even without multi-databases, a common mistake is to mix objects in
+different connections to the same database.
+
+    >>> conn2 = db1.open(transaction_manager=tm)
+
+    >>> p2 = MyClass()
+    >>> conn2.root()['p'] = p2
+    >>> p2.p1 = p1
+    >>> tm.commit() # doctest: +NORMALIZE_WHITESPACE
+    Traceback (most recent call last):
+    ...
+    InvalidObjectReference: Attempt to store a reference to an object
+    from a separate onnection to the same database or multidatabase
+
+    >>> tm.abort()
+
+"""
+
+
 def test_suite():
     return unittest.TestSuite((
         doctest.DocFileSuite('../cross-database-references.txt',
@@ -34,6 +87,7 @@
         doctest.DocFileSuite('../cross-database-references.txt',
                              globs=dict(MyClass=MyClass_w_getnewargs),
                              ),
+        doctest.DocTestSuite(),
         ))
 
 if __name__ == '__main__':



More information about the Zodb-checkins mailing list