]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Connections can be detached from their pool, closing on dereference instead of...
authorJason Kirtland <jek@discorporate.us>
Wed, 9 May 2007 22:39:50 +0000 (22:39 +0000)
committerJason Kirtland <jek@discorporate.us>
Wed, 9 May 2007 22:39:50 +0000 (22:39 +0000)
CHANGES
lib/sqlalchemy/pool.py
test/engine/pool.py

diff --git a/CHANGES b/CHANGES
index 1c13273d9d9554c59cec61a0779f08a844db739e..2e4862d1df58045c2dcd747f5f28d91a50246d7b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+- engines
+    - connections can be detached from their pool, closing on dereference
+      instead of returning to the pool for reuse
 - sql
     - _Label class overrides compare_self to return its ultimate object.
       meaning, if you say someexpr.label('foo') == 5, it produces
index 9a2cdad0e2d3ea0ba6993377b5e06e172363b5fc..6ad560e5b30846739e9728f70991fc7acb5a916a 100644 (file)
@@ -260,7 +260,8 @@ class _ConnectionFairy(object):
     def invalidate(self, e=None):
         if self.connection is None:
             raise exceptions.InvalidRequestError("This connection is closed")
-        self._connection_record.invalidate(e=e)
+        if self._connection_record is not None:
+            self._connection_record.invalidate(e=e)
         self.connection = None
         self._cursors = None
         self._close()
@@ -282,6 +283,12 @@ class _ConnectionFairy(object):
         self.__counter +=1
         return self
 
+    def detach(self):
+        if self._connection_record is not None:
+            self._connection_record.connection = None        
+            self._pool.do_return_conn(self._connection_record)
+            self._connection_record = None
+
     def close_open_cursors(self):
         if self._cursors is not None:
             for c in list(self._cursors):
@@ -307,6 +314,9 @@ class _ConnectionFairy(object):
         if self.connection is not None:
             try:
                 self.connection.rollback()
+                # Immediately close detached instances
+                if self._connection_record is None:
+                    self.connection.close()
             except Exception, e:
                 if self._connection_record is not None:
                     self._connection_record.invalidate(e=e)
index fdcdce2aa42a41f84c457d340c2133439a917322..315470e98b34c634cc57db21a094e610293c0bd6 100644 (file)
@@ -17,9 +17,10 @@ class MockConnection(object):
     def __init__(self):
         global mcid
         self.id = mcid
+        self.closed = False
         mcid += 1
     def close(self):
-        pass
+        self.closed = True
     def rollback(self):
         pass
     def cursor(self):
@@ -205,6 +206,30 @@ class PoolTest(PersistTest):
 
         c1 = p.connect()
         assert c1.connection.id != c_id
+
+    def test_detach(self):
+        dbapi = MockDBAPI()
+        p = pool.QueuePool(creator = lambda: dbapi.connect('foo.db'), pool_size = 1, max_overflow = 0, use_threadlocal = False)
+
+        c1 = p.connect()
+        c1.detach()
+        c_id = c1.connection.id
+
+        c2 = p.connect()
+        assert c2.connection.id != c1.connection.id
+        dbapi.raise_error = True
+
+        c2.invalidate()
+        c2 = None
+
+        c2 = p.connect()
+        assert c2.connection.id != c1.connection.id
+
+        con = c1.connection
+
+        assert not con.closed
+        c1.close()
+        assert con.closed
         
     def testthreadlocal_del(self):
         self._do_testthreadlocal(useclose=False)