[Checkins] SVN: z3c.dobbin/trunk/ Updated codebase to use
zope.sqlalchemy;
this consists of minor import-changes as well as reimplementing
support for concrete instances (this now uses a
before-commit-hook). Thanks to Lawrence Rowe for assistance.
Malthe Borch
mborch at gmail.com
Thu Jul 10 12:14:03 EDT 2008
Log message for revision 88194:
Updated codebase to use zope.sqlalchemy; this consists of minor import-changes as well as reimplementing support for concrete instances (this now uses a before-commit-hook). Thanks to Lawrence Rowe for assistance.
Changed:
U z3c.dobbin/trunk/README.txt
U z3c.dobbin/trunk/setup.py
U z3c.dobbin/trunk/src/z3c/dobbin/README.txt
U z3c.dobbin/trunk/src/z3c/dobbin/bootstrap.py
U z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
U z3c.dobbin/trunk/src/z3c/dobbin/relations.py
U z3c.dobbin/trunk/src/z3c/dobbin/session.py
U z3c.dobbin/trunk/src/z3c/dobbin/soup.py
U z3c.dobbin/trunk/src/z3c/dobbin/testing.py
U z3c.dobbin/trunk/src/z3c/dobbin/tests.py
A z3c.dobbin/trunk/src/z3c/dobbin/zs2sa.py
-=-
Modified: z3c.dobbin/trunk/README.txt
===================================================================
--- z3c.dobbin/trunk/README.txt 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/README.txt 2008-07-10 16:14:02 UTC (rev 88194)
@@ -16,5 +16,6 @@
-------
This package was designed and implemented by Malthe Borch, Stefan
-Eletzhofer. It's licensed as ZPL.
+Eletzhofer with parts contributed by Kapil Thangavelu and Laurence
+Rowe. It's licensed as ZPL.
Modified: z3c.dobbin/trunk/setup.py
===================================================================
--- z3c.dobbin/trunk/setup.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/setup.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -40,7 +40,6 @@
zip_safe=False,
extras_require = dict(
test = [
- 'zope.app.testing',
'pysqlite',
],
),
@@ -49,7 +48,8 @@
'zope.schema',
'zope.component',
'zope.dottedname',
- 'ore.alchemist',
- 'ZODB3',
+ 'zope.configuration',
+ 'z3c.saconfig',
+ 'transaction',
'SQLAlchemy==0.4.6'],
)
Modified: z3c.dobbin/trunk/src/z3c/dobbin/README.txt
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-07-10 16:14:02 UTC (rev 88194)
@@ -6,8 +6,8 @@
We begin with a new database session.
- >>> import ore.alchemist
- >>> session = ore.alchemist.Session()
+ >>> import z3c.saconfig
+ >>> session = z3c.saconfig.Session()
Mappers from interface specification
------------------------------------
@@ -78,15 +78,19 @@
>>> session.save(album)
>>> session.save(vinyl)
>>> session.save(cd)
+
+We must actually query the database once before proceeding; this seems
+to be a bug in ``zope.sqlalchemy``.
+ >>> results = session.query(album.__class__).all()
+
>>> import transaction
>>> transaction.commit()
We get a reference to the database metadata object, to locate each
underlying table.
- >>> from ore.alchemist.interfaces import IDatabaseEngine
- >>> engine = component.getUtility(IDatabaseEngine)
+ >>> engine = session.bind
>>> metadata = engine.metadata
Tables are given a name based on the dotted path of the interface they
Modified: z3c.dobbin/trunk/src/z3c/dobbin/bootstrap.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/bootstrap.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/bootstrap.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -2,17 +2,21 @@
import sqlalchemy as rdb
from sqlalchemy import orm
-
-import ore.alchemist.interfaces
+
+from z3c.saconfig.interfaces import IEngineFactory
+
import relations
class UUID(rdb.types.TypeEngine):
def get_col_spec(self):
return "UUID"
-def bootstrapDatabaseEngine(event):
- engine = component.getUtility(ore.alchemist.interfaces.IDatabaseEngine)
+def bootstrapDatabaseEngine(event=None):
+ factory = component.getUtility(IEngineFactory)
+ engine = factory()
engine.metadata = metadata = rdb.MetaData(engine)
+
+ # setup metadata
setUp(metadata)
def setUp(metadata):
Modified: z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -15,10 +15,8 @@
from sqlalchemy.orm.attributes import proxied_attribute_factory
-from ore.alchemist.interfaces import IDatabaseEngine
-from ore.alchemist import Session
-from ore.alchemist.zs2sa import FieldTranslator
-from ore.alchemist.zs2sa import StringTranslator
+from z3c.saconfig import Session
+from zs2sa import FieldTranslator, StringTranslator
from uuid import uuid1
from random import randint
@@ -148,7 +146,7 @@
def createMapper(spec):
"""Create a mapper for the specification."""
- engine = component.getUtility(IDatabaseEngine)
+ engine = Session().bind
metadata = engine.metadata
exclude = ['__name__']
Modified: z3c.dobbin/trunk/src/z3c/dobbin/relations.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/relations.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/relations.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -1,6 +1,6 @@
from zope import interface
-from ore.alchemist import Session
+from z3c.saconfig import Session
import soup
import factory
Modified: z3c.dobbin/trunk/src/z3c/dobbin/session.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/session.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/session.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -1,82 +1,21 @@
from zope import interface
-from transaction.interfaces import ISavepointDataManager
-from transaction import get as getTransaction
+from z3c.saconfig import Session
-from ore.alchemist import Session
-
import soup
+import transaction
-class Savepoint:
- """Transaction savepoint."""
+def beforeCommitHook(obj, uuid):
+ # unset pending state
+ session = Session()
+ del session._d_pending[uuid]
- def rollback(self):
- raise NotImplementedError("Rollbacks are not implemented.")
+ # build instance
+ instance = soup.lookup(uuid)
-class TransactionManager(object):
- """Transaction manager for the database session.
+ # update attributes
+ soup.update(instance, obj)
- This is used to synchronize relations to concrete items.
- """
-
- interface.implements(ISavepointDataManager)
-
- def __init__(self, obj, uuid):
- self.registered = False
- self.vote = False
- self.obj = obj
- self.uuid = uuid
-
- session = Session()
-
- try:
- session._d_pending[uuid] = obj
- except AttributeError:
- session._d_pending = {uuid: obj}
-
- def register(self):
- if not self.registered:
- getTransaction().join(self)
- self.registered = True
-
- def savepoint(self):
- return Savepoint()
-
- def tpc_begin(self, transaction):
- pass
-
- def commit(self, transaction):
- obj = self.obj
- uuid = self.uuid
-
- # unset pending state
- session = Session()
- del session._d_pending[uuid]
-
- # build instance
- instance = soup.lookup(uuid)
-
- # update attributes
- soup.update(instance, obj)
-
- def tpc_vote(self, transaction):
- pass
-
- def tpc_finish(self, transaction):
- self.registered = False
-
- def tpc_abort(self, transaction):
- # unset pending state
- session = Session()
- del session._d_pending[self.uuid]
-
- self.registered = False
-
- abort = tpc_abort
-
- def sortKey(self):
- return id(self)
-
def registerObject(obj, uuid):
session = Session()
@@ -86,5 +25,9 @@
pending = ()
if obj not in pending:
- TransactionManager(obj, uuid).register()
+ try:
+ session._d_pending[uuid] = obj
+ except AttributeError:
+ session._d_pending = {uuid: obj}
+ transaction.get().addBeforeCommitHook(beforeCommitHook, (obj, uuid))
Modified: z3c.dobbin/trunk/src/z3c/dobbin/soup.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/soup.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/soup.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -6,7 +6,7 @@
from session import registerObject
from zope.dottedname.resolve import resolve
-from ore.alchemist import Session
+from z3c.saconfig import Session
import factory
import bootstrap
Modified: z3c.dobbin/trunk/src/z3c/dobbin/testing.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/testing.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/testing.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -7,26 +7,28 @@
from sqlalchemy import orm
-from ore.alchemist import Session
-from ore.alchemist.interfaces import IDatabaseEngine
-
import z3c.dobbin
+from z3c.saconfig import EngineFactory
+from z3c.saconfig import GloballyScopedSession
+
metadata = rdb.MetaData()
def setUp(test):
- test._engine = rdb.create_engine('sqlite:///:memory:')
+ # provide engine factory
+ factory = EngineFactory('sqlite:///:memory:')
+ component.provideUtility(factory)
+
+ # setup scoped session
+ utility = GloballyScopedSession(autoflush=True)
+ component.provideUtility(utility)
- # register database engine
- component.provideUtility(test._engine, IDatabaseEngine)
-
# bootstrap database engine
- z3c.dobbin.bootstrap.bootstrapDatabaseEngine(None)
+ z3c.dobbin.bootstrap.bootstrapDatabaseEngine()
# register components
zope.configuration.xmlconfig.XMLConfig('meta.zcml', component)()
zope.configuration.xmlconfig.XMLConfig('configure.zcml', z3c.dobbin)()
def tearDown(test):
- del test._engine
- del metadata._bind
+ pass
Modified: z3c.dobbin/trunk/src/z3c/dobbin/tests.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/tests.py 2008-07-10 15:52:48 UTC (rev 88193)
+++ z3c.dobbin/trunk/src/z3c/dobbin/tests.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -5,7 +5,7 @@
from zope import schema
from zope import component
-from zope.app.testing import setup
+import zope.component.testing
from zope.testing.doctestunit import DocFileSuite
import transaction
@@ -13,12 +13,12 @@
import testing
def setUp(test):
- setup.placefulSetUp()
+ zope.component.testing.setUp(test)
testing.setUp(test)
def tearDown(test):
- setup.placefulTearDown()
testing.tearDown(test)
+ zope.component.testing.tearDown(test)
def test_suite():
globs = dict(
Added: z3c.dobbin/trunk/src/z3c/dobbin/zs2sa.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/zs2sa.py (rev 0)
+++ z3c.dobbin/trunk/src/z3c/dobbin/zs2sa.py 2008-07-10 16:14:02 UTC (rev 88194)
@@ -0,0 +1,68 @@
+from zope import schema
+import sqlalchemy as rdb
+
+class FieldTranslator( object ):
+ """ Translate a zope schema field to an sa column
+ """
+
+ def __init__(self, column_type):
+ self.column_type = column_type
+
+ def extractInfo( self, field, info ):
+ d = {}
+ d['name'] = field.getName()
+ if field.required:
+ d['nullable'] = False
+ d['default'] = field.default
+ d['type'] = self.column_type
+ return d
+
+ def __call__(self, field, annotation):
+ d = self.extractInfo( field, annotation )
+ name, type = d['name'], d['type']
+ del d['name']
+ del d['type']
+ return rdb.Column( name, type, **d)
+
+class StringTranslator(FieldTranslator):
+
+ column_type = rdb.Text
+
+ def __init__(self, column_type=None):
+ self.column_type = column_type or self.column_type
+
+ def extractInfo( self, field, info ):
+ d = super( StringTranslator, self ).extractInfo( field, info )
+ if schema.interfaces.IMinMaxLen.providedBy( field ):
+ d['type'].length = field.max_length
+ return d
+
+class ObjectTranslator(object):
+
+ def __call__(self, field, metadata):
+ table = transmute(field.schema, metadata)
+ pk = get_pk_name(table.name)
+ field_name = "%s.%s" % table.name, pk
+ return rdb.Column(pk, rdb.Integer, rdb.ForeignKey(field_name),
+ nullable=False)
+
+fieldmap = {
+ 'ASCII': StringTranslator(),
+ 'ASCIILine': StringTranslator(),
+ 'Bool': FieldTranslator(rdb.BOOLEAN),
+ 'Bytes': FieldTranslator(rdb.BLOB),
+ 'BytesLine': FieldTranslator(rdb.BLOB),
+ 'Choice': StringTranslator(),
+ 'Date': FieldTranslator(rdb.DATE),
+ 'Datetime': FieldTranslator(rdb.DATE),
+ 'DottedName': StringTranslator(),
+ 'Float': FieldTranslator(rdb.Float),
+ 'Id': StringTranslator(),
+ 'Int': FieldTranslator(rdb.Integer),
+ 'Object': ObjectTranslator(),
+ 'Password': StringTranslator(),
+ 'SourceText': StringTranslator(),
+ 'Text': StringTranslator(),
+ 'TextLine': StringTranslator(),
+ 'URI': StringTranslator(),
+}
More information about the Checkins
mailing list