[Checkins] SVN: zope.sqlalchemy/branches/savepoint-release/ savepoint.release() support
Laurence Rowe
l at lrowe.co.uk
Sat Jan 16 16:36:26 EST 2010
Log message for revision 108183:
savepoint.release() support
Changed:
A zope.sqlalchemy/branches/savepoint-release/
U zope.sqlalchemy/branches/savepoint-release/buildout.cfg
A zope.sqlalchemy/branches/savepoint-release/postgres.cfg
U zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/datamanager.py
U zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/tests.py
-=-
Modified: zope.sqlalchemy/branches/savepoint-release/buildout.cfg
===================================================================
--- zope.sqlalchemy/trunk/buildout.cfg 2010-01-16 19:29:40 UTC (rev 108182)
+++ zope.sqlalchemy/branches/savepoint-release/buildout.cfg 2010-01-16 21:36:25 UTC (rev 108183)
@@ -1,8 +1,23 @@
[buildout]
+allow-hosts = pypi.python.org
develop = .
-parts = test scripts
-allow-hosts = pypi.python.org
+parts =
+ test
+ scripts
+ test_transaction
+extensions = mr.developer
+sources = sources
+sources-dir = devel
+auto-checkout = transaction
+
+[sources]
+transaction = svn http://svn.zope.org/repos/main/transaction/branches/elro-savepoint-release
+
+[test_transaction]
+recipe = zc.recipe.testrunner
+eggs = transaction
+
[test]
recipe = zc.recipe.testrunner
eggs = zope.sqlalchemy [test]
Added: zope.sqlalchemy/branches/savepoint-release/postgres.cfg
===================================================================
--- zope.sqlalchemy/branches/savepoint-release/postgres.cfg (rev 0)
+++ zope.sqlalchemy/branches/savepoint-release/postgres.cfg 2010-01-16 21:36:25 UTC (rev 108183)
@@ -0,0 +1,61 @@
+# parts/postgresql/bin/postgres -D var/postgresql/ -d 1
+[buildout]
+extends = buildout.cfg
+find-links = http://initd.org/pub/software/psycopg/
+allow-hosts += initd.org
+
+parts +=
+ postgresql
+ postgresqlinit
+ psycopg2
+ test_pg
+ scripts
+
+[test_pg]
+recipe = zc.recipe.testrunner
+eggs =
+ zope.sqlalchemy [test]
+ psycopg2
+environment = testenv
+
+[scripts]
+eggs = ${test:eggs}
+
+[testenv]
+TEST_DSN = postgres://zope_sqlalchemy_tests:zope_sqlalchemy_tests@localhost:24004/zope_sqlalchemy_tests
+
+[postgresql]
+recipe = zc.recipe.cmmi
+url = ftp://ftp.postgresql.org/pub/source/v8.4.2/postgresql-8.4.2.tar.bz2
+md5sum = d738227e2f1f742d2f2d4ab56496c5c6
+extra_options =
+ --with-pgport=24004
+ --with-readline
+
+[postgresqlinit]
+recipe = iw.recipe.cmd
+on_install = true
+on_update = true
+datadir = ${buildout:directory}/var/postgresql
+cmds =
+ test -e ${buildout:directory}/bin/psql || \
+ ln -s ${postgresql:location}/bin/psql ${buildout:directory}/bin/psql
+ test -e ${postgresqlinit:datadir} && exit 0
+ ${postgresql:location}/bin/initdb ${postgresqlinit:datadir}
+ ${postgresql:location}/bin/postgres --single -D ${postgresqlinit:datadir} \
+ template1 << EOF
+ CREATE USER zope_sqlalchemy_tests WITH PASSWORD 'zope_sqlalchemy_tests';
+ CREATE DATABASE zope_sqlalchemy_tests OWNER zope_sqlalchemy_tests;
+ EOF
+ echo 'host all zope_sqlalchemy_tests 0.0.0.0/0 md5' \
+ >> ${postgresqlinit:datadir}/pg_hba.conf
+ echo "listen_addresses = '*'" >> ${postgresqlinit:datadir}/postgresql.conf
+
+[psycopg2]
+recipe = zc.recipe.egg:custom
+environment = psycopg2-env
+rpath = ${postgresql:location}/lib
+
+[psycopg2-env]
+# This is needed to help psycopg2 find the pg_config script
+PATH=${postgresql:location}/bin:%(PATH)s
Modified: zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/datamanager.py
===================================================================
--- zope.sqlalchemy/trunk/src/zope/sqlalchemy/datamanager.py 2010-01-16 19:29:40 UTC (rev 108182)
+++ zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/datamanager.py 2010-01-16 21:36:25 UTC (rev 108183)
@@ -22,6 +22,8 @@
STATUS_ACTIVE = 'active' # session joined to transaction, writes allowed.
STATUS_CHANGED = 'changed' # data has been written
STATUS_READONLY = 'readonly' # session joined to transaction, no writes allowed.
+STATUS_COMMITTING = 'committing' # session about to commit.
+
STATUS_INVALIDATED = STATUS_CHANGED # BBB
NO_SAVEPOINT_SUPPORT = set(['sqlite'])
@@ -74,6 +76,7 @@
def tpc_vote(self, trans):
# for a one phase data manager commit last in tpc_vote
if self.tx is not None: # there may have been no work to do
+ _SESSION_STATE[id(self.session)] = STATUS_COMMITTING
self.tx.commit()
self._finish('committed')
@@ -120,6 +123,7 @@
def tpc_finish(self, trans):
if self.tx is not None:
+ _SESSION_STATE[id(self.session)] = STATUS_COMMITTING
self.tx.commit()
self._finish('committed')
@@ -138,15 +142,25 @@
def __init__(self, session):
self.session = session
+ self.state = _SESSION_STATE[id(session)]
self.transaction = session.begin_nested()
- session.flush() # do I want to do this? Probably.
+ session.flush() # do I want to do this? Not needed in 0.5.
def rollback(self):
# no need to check validity, sqlalchemy should raise an exception. I think.
self.transaction.rollback()
+ _SESSION_STATE[id(self.session)] = self.state
self.session.clear() # remove when Session.rollback does an attribute_manager.rollback
+ def release(self):
+ state = _SESSION_STATE[id(self.session)]
+ try:
+ _SESSION_STATE[id(self.session)] = STATUS_COMMITTING
+ self.transaction.commit()
+ finally:
+ _SESSION_STATE[id(self.session)] = state
+
def join_transaction(session, initial_state=STATUS_ACTIVE):
"""Join a session to a transaction using the appropriate datamanager.
@@ -198,4 +212,4 @@
mark_changed(session)
def before_commit(self, session):
- assert zope_transaction.get().status == 'Committing', "Transaction must be committed using the transaction manager"
+ assert _SESSION_STATE[id(session)] == STATUS_COMMITTING, "Transaction must be committed using the transaction manager"
Modified: zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/tests.py
===================================================================
--- zope.sqlalchemy/trunk/src/zope/sqlalchemy/tests.py 2010-01-16 19:29:40 UTC (rev 108182)
+++ zope.sqlalchemy/branches/savepoint-release/src/zope/sqlalchemy/tests.py 2010-01-16 21:36:25 UTC (rev 108183)
@@ -297,6 +297,32 @@
s1.rollback()
self.failIf(query.all(), "Users table should be empty")
+ def testSavepointRelease(self):
+ use_savepoint = not engine.url.drivername in tx.NO_SAVEPOINT_SUPPORT
+ t = transaction.get()
+ session = Session()
+ query = session.query(User)
+ self.failIf(query.all(), "Users table should be empty")
+
+ s0 = t.savepoint(optimistic=True) # this should always work
+ self.failIf(query.all(), "Users table should be empty")
+
+ s1 = t.savepoint(optimistic=True)
+ session.add(User(id=1, firstname='udo', lastname='juergens'))
+ session.flush()
+ self.failUnless(len(query.all())==1, "Users table should have one row")
+
+ s2 = t.savepoint(optimistic=True)
+ session.add(User(id=2, firstname='heino', lastname='n/a'))
+ session.flush()
+ self.failUnless(len(query.all())==2, "Users table should have two rows")
+
+ s1.release()
+
+ if use_savepoint:
+ s0.rollback()
+ self.failIf(query.all(), "Users table should be empty")
+
def testCommit(self):
session = Session()
More information about the checkins
mailing list