[Zope-Checkins] CVS: ZODB3/ZODB - Connection.py:1.114.2.5

Steve Alexander steve at cat-box.net
Sun Feb 1 13:39:09 EST 2004


Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv3889

Modified Files:
      Tag: zope3-zodb3-devel-branch
	Connection.py 
Log Message:
Added an add(obj) method to Connection.

Added *unit* tests in the new file testConnection.py.


=== ZODB3/ZODB/Connection.py 1.114.2.4 => 1.114.2.5 ===
--- ZODB3/ZODB/Connection.py:1.114.2.4	Thu Jan 22 15:05:51 2004
+++ ZODB3/ZODB/Connection.py	Sun Feb  1 13:38:38 2004
@@ -27,7 +27,7 @@
 from ZODB.ConflictResolution import ResolvedSerial
 from ZODB.ExportImport import ExportImport
 from ZODB.POSException \
-     import ConflictError, ReadConflictError
+     import ConflictError, ReadConflictError, InvalidObjectReference
 from ZODB.TmpStore import TmpStore
 from ZODB.Transaction import Transaction, get_transaction
 from ZODB.utils import oid_repr, z64
@@ -80,6 +80,7 @@
             self._cache.cache_drain_resistance = 100
         self._incrgc = self.cacheGC = cache.incrgc
         self._committed = []
+        self._added = {}
         self._reset_counter = global_reset_counter
         self._load_count = 0   # Number of objects unghosted
         self._store_count = 0  # Number of objects stored
@@ -146,6 +147,9 @@
         obj = self._cache.get(oid, None)
         if obj is not None:
             return obj
+        obj = self._added.get(oid, None)
+        if obj is not None:
+            return obj
 
         p, serial = self._storage.load(oid, self._version)
         obj = self._reader.getGhost(p)
@@ -158,6 +162,19 @@
         self._cache[oid] = obj
         return obj
 
+    def add(self, obj):
+        marker = object()
+        oid = getattr(obj, "_p_oid", marker)
+        if oid is marker:
+            raise TypeError("Only first-class persistent objects may be"
+                            " added to a Connection.", obj)
+        elif obj._p_jar is None:
+            oid = obj._p_oid = self._storage.new_oid()
+            obj._p_jar = self
+            self._added[oid] = obj
+        elif obj._p_jar is not self:
+            raise InvalidObjectReference(obj, obj._p_jar)
+
     def sortKey(self):
         # XXX will raise an exception if the DB hasn't been set
         storage_key = self._sortKey()
@@ -205,8 +222,14 @@
         if object is self:
             self._flush_invalidations()
         else:
-            assert object._p_oid is not None
-            self._cache.invalidate(object._p_oid)
+            oid = object._p_oid
+            assert oid is not None
+            if oid in self._added:
+                del self._added[oid]
+                del object._p_jar
+                del object._p_oid
+            else:
+                self._cache.invalidate(object._p_oid)
 
     def cacheFullSweep(self, dt=0):
         self._cache.full_sweep(dt)
@@ -263,13 +286,21 @@
             raise ReadConflictError(object=object)
 
         invalid = self._invalid
+
+        # XXX In the case of a new object or an object added using add(),
+        #     the oid is appended to _creating.
+        #     However, this ought to be unnecessary because the _p_serial
+        #     of the object will be z64 or None, so it will be appended
+        #     to _creating about 30 lines down.
         if oid is None or object._p_jar is not self:
             # new object
             oid = self.new_oid()
             object._p_jar = self
             object._p_oid = oid
-            self._creating.append(oid)
-
+            self._creating.append(oid) # maybe don't need this
+        elif oid in self._added:
+            self._creating.append(oid) # maybe don't need this
+            del self._added[oid]
         elif object._p_changed:
             if invalid(oid):
                 resolve = getattr(object, "_p_resolveConflict", None)
@@ -583,6 +614,10 @@
         self._flush_invalidations()
         self._conflicts.clear()
         self._invalidate_creating()
+        while self._added:
+            oid, obj = self._added.popitem()
+            del obj._p_oid
+            del obj._p_jar
 
     def tpc_begin(self, transaction, sub=None):
         self._modified = []
@@ -672,6 +707,10 @@
 
         self._conflicts.clear()
         self._flush_invalidations()
+        # self._added should be empty at this point, because each object
+        # that add() was called for will have been either committed or
+        # aborted, or tpc_abort() will have been called.
+        assert not self._added, 'self._added not empty at end of tpc_finish'
 
     def sync(self):
         self.getTransaction().abort()




More information about the Zope-Checkins mailing list