[Zope-Checkins] CVS: Zope2 - Connection.py:1.50 ExportImport.py:1.11

shane@digicool.com shane@digicool.com
Sat, 14 Apr 2001 19:16:44 -0400 (EDT)


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

Modified Files:
	Connection.py ExportImport.py 
Log Message:
Changed object import so it happens in a subtransaction.  This cleans up
the undo log.



--- Updated File Connection.py in package Zope2/lib/python/ZODB --
--- Connection.py	2001/04/02 14:54:54	1.49
+++ Connection.py	2001/04/14 23:16:44	1.50
@@ -260,9 +260,20 @@
         # Return the connection to the pool.
         db._closeConnection(self)
                         
+    __onCommitActions=()
+    def onCommitAction(self, method_name, *args, **kw):
+        self.__onCommitActions = self.__onCommitActions + (
+            (method_name, args, kw),)
+        get_transaction().register(self)
+
     def commit(self, object, transaction, _type=type, _st=type('')):
         if object is self:
-            return # we registered ourself  
+            # We registered ourself.  Execute a commit action, if any.
+            if self.__onCommitActions:
+                method_name, args, kw = self.__onCommitActions[0]
+                self.__onCommitActions = self.__onCommitActions[1:]
+                apply(getattr(self, method_name), (transaction,) + args, kw)
+            return
         oid=object._p_oid
         invalid=self._invalid
         if oid is None or object._p_jar is not self:
@@ -413,6 +424,7 @@
 
     def commit_sub(self, t,
                    _type=type, _st=type(''), _None=None):
+        """Commit all work done in subtransactions"""
         tmp=self._tmp
         if tmp is _None: return
         src=self._storage
@@ -597,6 +609,7 @@
             raise
 
     def tpc_abort(self, transaction):
+        self.__onCommitActions = ()
         self._storage.tpc_abort(transaction)
         cache=self._cache
         cache.invalidate(self._invalidated)
@@ -622,6 +635,7 @@
 
     def tpc_vote(self, transaction,
                  _type=type, _st=type('')):
+        self.__onCommitActions = ()
         try: vote=self._storage.tpc_vote
         except: return
         s=vote(transaction)

--- Updated File ExportImport.py in package Zope2/lib/python/ZODB --
--- ExportImport.py	2000/08/08 17:48:50	1.10
+++ ExportImport.py	2001/04/14 23:16:44	1.11
@@ -142,22 +142,35 @@
                 return customImporters[magic](self, file, clue)
             raise POSException.ExportError, 'Invalid export header'
 
-        t=get_transaction().sub()
-
-        t.note('import into %s from %s' % (self.db().getName(), file_name))
+        t = get_transaction()
         if clue: t.note(clue)
+
+        return_oid_list = []
+        self.onCommitAction('_importDuringCommit', file, return_oid_list)
+        t.commit(1)
+        # Return the root imported object.
+        if return_oid_list:
+            return self[return_oid_list[0]]
+        else:
+            return None
 
-        storage=self._storage
-        new_oid=storage.new_oid
-        oids={}
-        wrote_oid=oids.has_key
-        new_oid=storage.new_oid
-        store=storage.store
+    def _importDuringCommit(self, transaction, file, return_oid_list):
+        '''
+        Invoked by the transaction manager mid commit.
+        Appends one item, the OID of the first object created,
+        to return_oid_list.
+        '''
+        oids = {}
+        storage = self._storage
+        new_oid = storage.new_oid
+        store = storage.store
+        read = file.read
 
         def persistent_load(ooid,
                             Ghost=Ghost, StringType=StringType,
                             atoi=string.atoi, TupleType=type(()),
-                            oids=oids, wrote_oid=wrote_oid, new_oid=new_oid):
+                            oids=oids, wrote_oid=oids.has_key,
+                            new_oid=storage.new_oid):
         
             "Remap a persistent id to a new ID and create a ghost for it."
 
@@ -174,51 +187,42 @@
             Ghost.oid=oid
             return Ghost
 
-        version=self._version
-        return_oid=None
+        version = self._version
 
-        storage.tpc_begin(t)
-        try:
-            while 1:
-                h=read(16)
-                if h==export_end_marker: break
-                if len(h) != 16:
-                    raise POSException.ExportError, 'Truncated export file'
-                l=u64(h[8:16])
-                p=read(l)
-                if len(p) != l:
-                    raise POSException.ExportError, 'Truncated export file'
-
-                ooid=h[:8]
-                if oids:
-                    oid=oids[ooid]
-                    if type(oid) is TupleType: oid=oid[0]
-                else:
-                    oids[ooid]=return_oid=oid=new_oid()
-
-                pfile=StringIO(p)
-                unpickler=Unpickler(pfile)
-                unpickler.persistent_load=persistent_load
-
-                newp=StringIO()
-                pickler=Pickler(newp,1)
-                pickler.persistent_id=persistent_id
-
-                pickler.dump(unpickler.load())
-                pickler.dump(unpickler.load())
-                p=newp.getvalue()
-                plen=len(p)
-
-                store(oid, None, p, version, t)
-                
-        except:
-            storage.tpc_abort(t)
-            raise
-        else:
-            storage.tpc_vote(t)
-            storage.tpc_finish(t)
-            if return_oid is not None: return self[return_oid]
+        while 1:
+            h=read(16)
+            if h==export_end_marker: break
+            if len(h) != 16:
+                raise POSException.ExportError, 'Truncated export file'
+            l=u64(h[8:16])
+            p=read(l)
+            if len(p) != l:
+                raise POSException.ExportError, 'Truncated export file'
+
+            ooid=h[:8]
+            if oids:
+                oid=oids[ooid]
+                if type(oid) is TupleType: oid=oid[0]
+            else:
+                oids[ooid] = oid = storage.new_oid()
+                return_oid_list.append(oid)
 
+            pfile=StringIO(p)
+            unpickler=Unpickler(pfile)
+            unpickler.persistent_load=persistent_load
+
+            newp=StringIO()
+            pickler=Pickler(newp,1)
+            pickler.persistent_id=persistent_id
+
+            pickler.dump(unpickler.load())
+            pickler.dump(unpickler.load())
+            p=newp.getvalue()
+            plen=len(p)
+
+            store(oid, None, p, version, transaction)
+
+
 StringType=type('')
 
 def TemporaryFile():
@@ -233,6 +237,6 @@
 class Ghost: pass
 
 def persistent_id(object, Ghost=Ghost):
-    if hasattr(object, '__class__') and object.__class__ is Ghost:
+    if getattr(object, '__class__', None) is Ghost:
         return object.oid
-    
+



--- Updated File Connection.py in package Zope2 --
--- Connection.py	2001/04/02 14:54:54	1.49
+++ Connection.py	2001/04/14 23:16:44	1.50
@@ -260,9 +260,20 @@
         # Return the connection to the pool.
         db._closeConnection(self)
                         
+    __onCommitActions=()
+    def onCommitAction(self, method_name, *args, **kw):
+        self.__onCommitActions = self.__onCommitActions + (
+            (method_name, args, kw),)
+        get_transaction().register(self)
+
     def commit(self, object, transaction, _type=type, _st=type('')):
         if object is self:
-            return # we registered ourself  
+            # We registered ourself.  Execute a commit action, if any.
+            if self.__onCommitActions:
+                method_name, args, kw = self.__onCommitActions[0]
+                self.__onCommitActions = self.__onCommitActions[1:]
+                apply(getattr(self, method_name), (transaction,) + args, kw)
+            return
         oid=object._p_oid
         invalid=self._invalid
         if oid is None or object._p_jar is not self:
@@ -413,6 +424,7 @@
 
     def commit_sub(self, t,
                    _type=type, _st=type(''), _None=None):
+        """Commit all work done in subtransactions"""
         tmp=self._tmp
         if tmp is _None: return
         src=self._storage
@@ -597,6 +609,7 @@
             raise
 
     def tpc_abort(self, transaction):
+        self.__onCommitActions = ()
         self._storage.tpc_abort(transaction)
         cache=self._cache
         cache.invalidate(self._invalidated)
@@ -622,6 +635,7 @@
 
     def tpc_vote(self, transaction,
                  _type=type, _st=type('')):
+        self.__onCommitActions = ()
         try: vote=self._storage.tpc_vote
         except: return
         s=vote(transaction)

--- Updated File ExportImport.py in package Zope2 --
--- ExportImport.py	2000/08/08 17:48:50	1.10
+++ ExportImport.py	2001/04/14 23:16:44	1.11
@@ -142,22 +142,35 @@
                 return customImporters[magic](self, file, clue)
             raise POSException.ExportError, 'Invalid export header'
 
-        t=get_transaction().sub()
-
-        t.note('import into %s from %s' % (self.db().getName(), file_name))
+        t = get_transaction()
         if clue: t.note(clue)
+
+        return_oid_list = []
+        self.onCommitAction('_importDuringCommit', file, return_oid_list)
+        t.commit(1)
+        # Return the root imported object.
+        if return_oid_list:
+            return self[return_oid_list[0]]
+        else:
+            return None
 
-        storage=self._storage
-        new_oid=storage.new_oid
-        oids={}
-        wrote_oid=oids.has_key
-        new_oid=storage.new_oid
-        store=storage.store
+    def _importDuringCommit(self, transaction, file, return_oid_list):
+        '''
+        Invoked by the transaction manager mid commit.
+        Appends one item, the OID of the first object created,
+        to return_oid_list.
+        '''
+        oids = {}
+        storage = self._storage
+        new_oid = storage.new_oid
+        store = storage.store
+        read = file.read
 
         def persistent_load(ooid,
                             Ghost=Ghost, StringType=StringType,
                             atoi=string.atoi, TupleType=type(()),
-                            oids=oids, wrote_oid=wrote_oid, new_oid=new_oid):
+                            oids=oids, wrote_oid=oids.has_key,
+                            new_oid=storage.new_oid):
         
             "Remap a persistent id to a new ID and create a ghost for it."
 
@@ -174,51 +187,42 @@
             Ghost.oid=oid
             return Ghost
 
-        version=self._version
-        return_oid=None
+        version = self._version
 
-        storage.tpc_begin(t)
-        try:
-            while 1:
-                h=read(16)
-                if h==export_end_marker: break
-                if len(h) != 16:
-                    raise POSException.ExportError, 'Truncated export file'
-                l=u64(h[8:16])
-                p=read(l)
-                if len(p) != l:
-                    raise POSException.ExportError, 'Truncated export file'
-
-                ooid=h[:8]
-                if oids:
-                    oid=oids[ooid]
-                    if type(oid) is TupleType: oid=oid[0]
-                else:
-                    oids[ooid]=return_oid=oid=new_oid()
-
-                pfile=StringIO(p)
-                unpickler=Unpickler(pfile)
-                unpickler.persistent_load=persistent_load
-
-                newp=StringIO()
-                pickler=Pickler(newp,1)
-                pickler.persistent_id=persistent_id
-
-                pickler.dump(unpickler.load())
-                pickler.dump(unpickler.load())
-                p=newp.getvalue()
-                plen=len(p)
-
-                store(oid, None, p, version, t)
-                
-        except:
-            storage.tpc_abort(t)
-            raise
-        else:
-            storage.tpc_vote(t)
-            storage.tpc_finish(t)
-            if return_oid is not None: return self[return_oid]
+        while 1:
+            h=read(16)
+            if h==export_end_marker: break
+            if len(h) != 16:
+                raise POSException.ExportError, 'Truncated export file'
+            l=u64(h[8:16])
+            p=read(l)
+            if len(p) != l:
+                raise POSException.ExportError, 'Truncated export file'
+
+            ooid=h[:8]
+            if oids:
+                oid=oids[ooid]
+                if type(oid) is TupleType: oid=oid[0]
+            else:
+                oids[ooid] = oid = storage.new_oid()
+                return_oid_list.append(oid)
 
+            pfile=StringIO(p)
+            unpickler=Unpickler(pfile)
+            unpickler.persistent_load=persistent_load
+
+            newp=StringIO()
+            pickler=Pickler(newp,1)
+            pickler.persistent_id=persistent_id
+
+            pickler.dump(unpickler.load())
+            pickler.dump(unpickler.load())
+            p=newp.getvalue()
+            plen=len(p)
+
+            store(oid, None, p, version, transaction)
+
+
 StringType=type('')
 
 def TemporaryFile():
@@ -233,6 +237,6 @@
 class Ghost: pass
 
 def persistent_id(object, Ghost=Ghost):
-    if hasattr(object, '__class__') and object.__class__ is Ghost:
+    if getattr(object, '__class__', None) is Ghost:
         return object.oid
-    
+