[Zodb-checkins] CVS: Zope2/lib/python/ZODB - DB.py:1.27

Jim Fulton jim@digicool.com
Thu, 12 Apr 2001 15:53:05 -0400 (EDT)


Update of /cvs-repository/Zope2/lib/python/ZODB
In directory korak:/tmp/cvs-serv26216

Modified Files:
	DB.py 
Log Message:
Added support for transactional undo. This allows transactions to be
undone and then redone, if the underlying storage supports
transactionalUndo.

Also fixed a bug in an unused method. The bug causes warnings in
Python 2.1.



--- Updated File DB.py in package Zope2/lib/python/ZODB --
--- DB.py	2000/10/11 22:16:52	1.26
+++ DB.py	2001/04/12 19:53:04	1.27
@@ -165,10 +165,11 @@
 
         if hasattr(storage, 'undoInfo'):
             self.undoInfo=storage.undoInfo
+            
 
     def _cacheMean(self, attr):
         m=[0,0]
-        def f(con, m=m):
+        def f(con, m=m, attr=attr):
             t=getattr(con._cache,attr)
             m[0]=m[0]+t
             m[1]=m[1]+1
@@ -568,9 +569,21 @@
     def cacheStatistics(self): return () # :(
 
     def undo(self, id):
-        for oid in self._storage.undo(id):
-            self.invalidate(oid)
+        storage=self._storage
+        try: supportsTransactionalUndo = storage.supportsTransactionalUndo
+        except AttributeError:
+            supportsTransactionalUndo=0
+        else:
+            supportsTransactionalUndo=supportsTransactionalUndo()
 
+        if supportsTransactionalUndo:
+            # new style undo
+            TransactionalUndo(self, id)
+        else:
+            # fall back to old undo
+            for oid in storage.undo(id):
+                self.invalidate(oid)
+
     def versionEmpty(self, version):
         return self._storage.versionEmpty(version)
 
@@ -611,5 +624,23 @@
     def commit(self, reallyme, t):
         db=self._db
         version=self._version
-        for oid in db._storage.abortVersion(version, t):
+        oids = db._storage.abortVersion(version, t)
+        for oid in oids:
             db.invalidate(oid, version=version)
+
+
+class TransactionalUndo(CommitVersion):
+    """An object that will see to transactional undo
+
+    in cooperation with a transaction manager.
+    """
+    
+    # I'm lazy. I'm reusing __init__ and abort and reusing the
+    # version attr for the transavtion id. There's such a strong
+    # similarity of rythm, that I think it's justified.
+
+    def commit(self, reallyme, t):
+        db=self._db
+        oids=db._storage.transactionalUndo(self._version, t)
+        for oid in oids:
+            db.invalidate(oid)