[Zodb-checkins] CVS: Zope3/lib/python/ZODB - BaseStorage.py:1.15.10.6 DB.py:1.34.4.9 FileStorage.py:1.75.10.4

Jeremy Hylton jeremy@zope.com
Fri, 29 Mar 2002 17:24:00 -0500


Update of /cvs-repository/Zope3/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv23597

Modified Files:
      Tag: Zope-3x-branch
	BaseStorage.py DB.py FileStorage.py 
Log Message:
Remove support for old-style undo().

Transactional undo is preferred in Zope 2.5 and up.  For Zope3,
transactional undo will be the only undo.  Also simplify
implementation of undoInfo() and undoLog().  undoInfo() is preferred
for all uses.  To the extent that undoLog() remains, it is a helper to
implement undoInfo().

Remove undo() from ReadOnlyStorage tests, since it isn't part of the
API anymore.


=== Zope3/lib/python/ZODB/BaseStorage.py 1.15.10.5 => 1.15.10.6 ===
 
 import threading
-import time, UndoLogCompatible
+import time
 import POSException
 from TimeStamp import TimeStamp
 z64='\0'*8
 
-class BaseStorage(UndoLogCompatible.UndoLogCompatible):
+class BaseStorage:
     _transaction=None # Transaction that is being committed
     _serial=z64       # Transaction serial number
     _tstatus=' '      # Transaction status, used for copying data
@@ -97,9 +97,6 @@
     def isReadOnly(self):
         return self._is_read_only
     
-    def supportsUndo(self):
-        return 0
-    
     def supportsVersions(self):
         return 0
         
@@ -196,10 +193,38 @@
         """
         pass
 
-    def undo(self, transaction_id):
-        if self._is_read_only:
-            raise POSException.ReadOnlyError()
-        raise POSException.UndoError, 'non-undoable transaction'
+    def undoInfo(self, first=0, last=-20, specification=None):
+        """Return a list of transaction descriptions for use with undo.
+
+        The first and last argument specify how many transactions to
+        return and where in the transaction history they should come
+        from.  The specification argument is a mapping that specifies
+        a filter on transaction metadata.
+
+        undoInfo() scans the transaction history from most recent
+        transaction to oldest transaction.  It skips the 'first' most
+        recent transactions; i.e. if first is N, then the first
+        transaction returned will be the Nth transaction.
+
+        If last is less than zero, then its absolute value is the
+        maximum number of transactions to return.  Otherwise if last
+        is N, then only the N most recent transactions following start
+        are considered.
+
+        If specification is not None, then it must be a mapping that
+        is compared to the transaction description.  Each key-value
+        pair in the specification must also be present in the
+        description.
+        """
+        if specification:
+            def filter(desc, spec=specification.items()):
+                for k, v in spec:
+                    if desc.get(k) != v:
+                        return 0
+                return 1
+        else:
+            filter = None
+        return self.undoLog(first, last, filter)
 
     def undoLog(self, first, last, filter=None):
         return ()


=== Zope3/lib/python/ZODB/DB.py 1.34.4.8 => 1.34.4.9 ===
 """
 
-import cPickle, cStringIO, sys, POSException, UndoLogCompatible
+import cPickle, cStringIO, sys
+import POSException
 from Connection import Connection
 from threading import Lock
 from Transaction import Transaction
@@ -26,7 +27,7 @@
 
 from types import StringType
 
-class DB(UndoLogCompatible.UndoLogCompatible):
+class DB:
     """The Object Database
 
     The Object database coordinates access to and interaction of one
@@ -90,15 +91,10 @@
             storage.tpc_finish(t)
 
         # Pass through methods:
-        for m in ('history',
-                  'supportsUndo', 'supportsVersions', 'undoLog',
-                  'versionEmpty', 'versions'):
+        for m in ('history', 'supportsVersions', 'undoInfo', 'versionEmpty',
+                  'versions'):
             setattr(self, m, getattr(storage, m))
 
-        if hasattr(storage, 'undoInfo'):
-            self.undoInfo=storage.undoInfo
-            
-
     def _cacheMean(self, attr):
         # XXX this method doesn't work
         m=[0,0]
@@ -528,20 +524,7 @@
     def cacheStatistics(self): return () # :(
 
     def undo(self, id):
-        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)
+        TransactionalUndo(self, id)
 
     def versionEmpty(self, version):
         return self._storage.versionEmpty(version)


=== Zope3/lib/python/ZODB/FileStorage.py 1.75.10.3 => 1.75.10.4 ===
             self._nextpos=0
 
-    def undo(self, transaction_id):
-        if self._is_read_only:
-            raise POSException.ReadOnlyError()
-        self._lock_acquire()
-        try:
-            self._clear_index()
-            transaction_id=base64.decodestring(transaction_id+'==\n')
-            tid, tpos = transaction_id[:8], U64(transaction_id[8:])
-            packt=self._packt
-            if packt is None or packt > tid:
-                raise UndoError, (
-                    'Undo is currently disabled for database maintenance.<p>')
-
-            file=self._file
-            seek=file.seek
-            read=file.read
-            index_get=self._index_get
-            unpack=struct.unpack
-            seek(tpos)
-            h=read(TRANS_HDR_LEN)
-            if len(h) != TRANS_HDR_LEN or h[:8] != tid: 
-                raise UndoError('Invalid undo transaction id')
-            if h[16] == 'u': return
-            if h[16] != ' ': raise UndoError
-            tl=U64(h[8:16])
-            ul,dl,el=unpack(">HHH", h[17:TRANS_HDR_LEN])
-            tend=tpos+tl
-            pos=tpos+(TRANS_HDR_LEN+ul+dl+el)
-            t={}
-            while pos < tend:
-                # Read the data records for this transaction
-                seek(pos)
-                h=read(DATA_HDR_LEN)
-                oid,serial,sprev,stloc,vlen,splen = unpack(">8s8s8s8sH8s", h)
-                plen=U64(splen)
-                prev=U64(sprev)
-                dlen=DATA_HDR_LEN+(plen or 8)
-                if vlen: dlen=dlen+(16+vlen)
-                if index_get(oid, 0) != pos: raise UndoError
-                pos=pos+dlen
-                if pos > tend: raise UndoError
-                t[oid]=prev
-
-            seek(tpos+16)
-            file.write('u')
-            file.flush()
-            self._index.update(t)
-            return t.keys()            
-        finally: self._lock_release()
-
     def supportsTransactionalUndo(self):
         return 1