[Checkins] SVN: z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/ refactored datamanger for better reusability

Andreas Jung andreas at andreas-jung.com
Sat Mar 15 17:17:44 EDT 2008


Log message for revision 84678:
  refactored datamanger for better reusability
  

Changed:
  U   z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/datamanager.py
  A   z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/tm.py

-=-
Modified: z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/datamanager.py
===================================================================
--- z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/datamanager.py	2008-03-15 21:14:05 UTC (rev 84677)
+++ z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/datamanager.py	2008-03-15 21:17:43 UTC (rev 84678)
@@ -28,45 +28,9 @@
 from sqlalchemy.orm.mapper import global_extensions
 
 from sqlalchemy.orm import scoped_session, sessionmaker
+from tm import *
 
 
-class AlchemyEngineUtility(persistent.Persistent):
-    """A utility providing a database engine.
-    """
-
-    implements(z3c.zalchemy.interfaces.IAlchemyEngineUtility)
-
-    def __init__(self, name, dsn, echo=False, encoding='utf-8',
-                 convert_unicode=False, **kwargs):
-        self.name = name
-        self.dsn = dsn
-        self.encoding = encoding
-        self.convert_unicode = convert_unicode
-        self.echo = echo
-        self.kw={}
-        self.kw.update(kwargs)
-
-    def getEngine(self):
-        engine = getattr(self, '_v_engine', None)
-        if engine:
-            return engine
-        # create_engine consumes the keywords, so better to make a copy first
-        kw = {}
-        kw.update(self.kw)
-        # create a new engine and configure it thread-local
-        self._v_engine = sqlalchemy.create_engine(
-            self.dsn, echo=self.echo, encoding=self.encoding,
-            convert_unicode=self.convert_unicode,
-            strategy='threadlocal', **kw)
-        return self._v_engine
-
-    def _resetEngine(self):
-        engine = getattr(self, '_v_engine', None)
-        if engine is not None:
-            engine.dispose()
-            self._v_engine = None
-
-
 for name in z3c.zalchemy.interfaces.IAlchemyEngineUtility:
     setattr(AlchemyEngineUtility, name, FieldProperty(
         z3c.zalchemy.interfaces.IAlchemyEngineUtility[name]))
@@ -257,26 +221,6 @@
             raise conflict
 
 
-class AlchemySavepoint(object):
-    """A savepoint for the AlchemyDataManager that only supports optimistic
-    savepoints.
-
-    """
-
-    implements(IDataManagerSavepoint)
-
-    def __init__(self, transaction, session):
-        self.transaction = transaction
-        self.session = session
-
-    def rollback(self):
-        # Savepoints expire the objects so they get reloaded with the old
-        # state
-        self.transaction.rollback()
-        for obj in self.session:
-            self.session.expire(obj)
-
-
 class MetaManager(object):
     """A manager for metadata to be able to use the same table name in
     different databases.

Added: z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/tm.py
===================================================================
--- z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/tm.py	                        (rev 0)
+++ z3c.zalchemy/branches/ajung-tm-refactor/src/z3c/zalchemy/tm.py	2008-03-15 21:17:43 UTC (rev 84678)
@@ -0,0 +1,148 @@
+##############################################################################
+#
+# Copyright (c) 2006 ROBOTECH Logistiksysteme GmbH and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import persistent
+import transaction
+from zope.interface import implements
+from zope.component import queryUtility, getUtility, getUtilitiesFor
+from zope.schema.fieldproperty import FieldProperty
+
+from transaction.interfaces import IDataManager, ISynchronizer
+from transaction.interfaces import IDataManagerSavepoint
+
+import z3c.zalchemy.interfaces
+
+import sqlalchemy
+import sqlalchemy.orm
+from sqlalchemy.orm.mapper import global_extensions
+
+from sqlalchemy.orm import scoped_session, sessionmaker
+
+
+class AlchemyEngineUtility(persistent.Persistent):
+    """A utility providing a database engine.
+    """
+
+    implements(z3c.zalchemy.interfaces.IAlchemyEngineUtility)
+
+    def __init__(self, name, dsn, echo=False, encoding='utf-8',
+                 convert_unicode=False, **kwargs):
+        self.name = name
+        self.dsn = dsn
+        self.encoding = encoding
+        self.convert_unicode = convert_unicode
+        self.echo = echo
+        self.kw={}
+        self.kw.update(kwargs)
+
+    def getEngine(self):
+        engine = getattr(self, '_v_engine', None)
+        if engine:
+            return engine
+        # create_engine consumes the keywords, so better to make a copy first
+        kw = {}
+        kw.update(self.kw)
+        # create a new engine and configure it thread-local
+        self._v_engine = sqlalchemy.create_engine(
+            self.dsn, echo=self.echo, encoding=self.encoding,
+            convert_unicode=self.convert_unicode,
+            strategy='threadlocal', **kw)
+        return self._v_engine
+
+    def _resetEngine(self):
+        engine = getattr(self, '_v_engine', None)
+        if engine is not None:
+            engine.dispose()
+            self._v_engine = None
+
+
+class AlchemyDataManager(object):
+    """Takes care of the transaction process in Zope. """
+
+    implements(IDataManager)
+
+    def __init__(self, session):
+        self.session = session
+
+    def abort(self, trans):
+        self._abort()
+
+    def commit(self, trans):
+        # Flush instructions to the database (because of conflict integration)
+        self._flush_session()
+        # Commit any nested transactions (savepoints)
+        while self.session.transaction.nested:
+            self.session.commit()
+
+    def tpc_begin(self, trans):
+        pass
+
+    def tpc_vote(self, trans):
+        pass
+
+    def tpc_finish(self, trans):
+        self.session.commit()
+        self._cleanup()
+
+    def tpc_abort(self, trans):
+        self._abort()
+
+    def sortKey(self):
+        return str(id(self))
+
+    def savepoint(self):
+        self._flush_session()
+        transaction = self.session.begin_nested()
+        self._flush_session()
+        return AlchemySavepoint(transaction, self.session)
+
+    def _cleanup(self):
+        Session.remove()
+
+    def _abort(self):
+        while self.session.transaction.nested:
+            self.session.transaction.close()
+        self.session.rollback()
+        self._cleanup()
+
+    def _flush_session(self):
+        try:
+            self.session.flush()
+        except Exception, e:
+            conflict = z3c.zalchemy.interfaces.IConflictError(e, None)
+            if conflict is None:
+                raise
+            raise conflict
+
+
+class AlchemySavepoint(object):
+    """A savepoint for the AlchemyDataManager that only supports optimistic
+    savepoints.
+
+    """
+
+    implements(IDataManagerSavepoint)
+
+    def __init__(self, transaction, session):
+        self.transaction = transaction
+        self.session = session
+
+    def rollback(self):
+        # Savepoints expire the objects so they get reloaded with the old
+        # state
+        self.transaction.rollback()
+        for obj in self.session:
+            self.session.expire(obj)
+
+



More information about the Checkins mailing list