Author: phd
Date: 2006-02-07 09:30:50 -0700 (Tue, 07 Feb 2006)
New Revision: 1583
Modified:
home/phd/SQLObject/paramstyles/sqlobject/cache.py
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py
Log:
Merged patches from the revisions 1580:1582 from the trunk: applied the patch 1370278: synchronize main connection cache during transaction commit.
Modified: home/phd/SQLObject/paramstyles/sqlobject/cache.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/cache.py 2006-02-07 16:29:27 UTC (rev 1582)
+++ home/phd/SQLObject/paramstyles/sqlobject/cache.py 2006-02-07 16:30:50 UTC (rev 1583)
@@ -316,8 +316,11 @@
self.caches[cls.__name__].clear()
def tryGet(self, id, cls):
+ return self.tryGetByName(id, cls.__name__)
+
+ def tryGetByName(self, id, clsname):
try:
- return self.caches[cls.__name__].tryGet(id)
+ return self.caches[clsname].tryGet(id)
except KeyError:
return None
@@ -330,6 +333,9 @@
def allSubCaches(self):
return self.caches.values()
+ def allSubCachesByClassNames(self):
+ return self.caches
+
def weakrefAll(self, cls=None):
"""
Move all objects in the cls (or if not given, then in all
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-02-07 16:29:27 UTC (rev 1582)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-02-07 16:30:50 UTC (rev 1583)
@@ -801,6 +801,7 @@
self._connection = dbConnection.getConnection()
self._dbConnection._setAutoCommit(self._connection, 0)
self.cache = CacheSet(cache=dbConnection.doCache)
+ self._deletedCache = {}
def assertActive(self):
assert not self._obsolete, "This transaction has already gone through ROLLBACK; begin another transaction"
@@ -832,6 +833,13 @@
return iter(list(select.IterationClass(self, self._connection,
select, keepConnection=True)))
+ def _SO_delete(self, inst):
+ cls = inst.__class__.__name__
+ if not self._deletedCache.has_key(cls):
+ self._deletedCache[cls] = []
+ self._deletedCache[cls].append(inst.id)
+ return self._dbConnection._SO_delete(inst)
+
def commit(self, close=False):
if self._obsolete:
# @@: is it okay to get extraneous commits?
@@ -841,6 +849,13 @@
self._connection.commit()
if close:
self._makeObsolete()
+ subCaches = [(sub[0], sub[1].allIDs()) for sub in self.cache.allSubCachesByClassNames().items()]
+ subCaches.extend([(x[0], x[1]) for x in self._deletedCache.items()])
+ for cls, ids in subCaches:
+ for id in ids:
+ inst = self._dbConnection.cache.tryGetByName(id, cls)
+ if inst is not None:
+ inst.expire()
def rollback(self):
if self._obsolete:
@@ -884,6 +899,7 @@
self._dbConnection.releaseConnection(self._connection,
explicit=True)
self._connection = None
+ self._deletedCache = {}
def begin(self):
# @@: Should we do this, or should begin() be a no-op when we're
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py 2006-02-07 16:29:27 UTC (rev 1582)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py 2006-02-07 16:30:50 UTC (rev 1583)
@@ -36,3 +36,18 @@
finally:
TestSOTrans._connection.autoCommit = True
+def test_transaction_commit_sync():
+ if not supports('transactions'):
+ return
+ setupClass(TestSOTrans)
+ trans = TestSOTrans._connection.transaction()
+ try:
+ TestSOTrans(name='bob')
+ bOut = TestSOTrans.byName('bob')
+ bIn = TestSOTrans.byName('bob', connection=trans)
+ bIn.name = 'robert'
+ assert bOut.name == 'bob'
+ trans.commit()
+ assert bOut.name == 'robert'
+ finally:
+ TestSOTrans._connection.autoCommit = True
|