]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- connection pool tracks open cursors and raises an error if connection
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Sep 2006 20:18:41 +0000 (20:18 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Sep 2006 20:18:41 +0000 (20:18 +0000)
is returned to pool with cursors still opened.  fixes issues with MySQL,
others

CHANGES
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/pool.py

diff --git a/CHANGES b/CHANGES
index e077877c36b337b41754674712e84d302df39bee..438b1993f609a07e55fa21784e438661513fe65f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -37,6 +37,9 @@ to before_XXXX and after_XXXX
 - added autoincrement=True to Column; will disable schema generation
 of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
 explicitly set to False
+- connection pool tracks open cursors and raises an error if connection
+is returned to pool with cursors still opened.  fixes issues with MySQL, 
+others
 
 0.2.8
 - cleanup on connection methods + documentation.  custom DBAPI
index cf321bca2bd8e5157c9b852bfe3763ff735e252e..28d5ea94e658d2238163e560479e4d78ffface43 100644 (file)
@@ -211,6 +211,7 @@ class Connection(Connectable):
         if self.__engine.echo:
             self.__engine.log("ROLLBACK")
         self.__engine.dialect.do_rollback(self.connection)
+        self.__connection.close_open_cursors()
         self.__transaction = None
     def _commit_impl(self):
         if self.__engine.echo:
@@ -643,7 +644,7 @@ class ResultProxy:
             # and not just plain tuples ?
             self.close()
             return None
-
+    
 class RowProxy:
     """proxies a single cursor row for a parent ResultProxy."""
     def __init__(self, parent, row):
index de987278d48ebd254d55ee32fd06195e82529151..9eb9cd2ff8743a27e3acc89ed499380489846626 100644 (file)
@@ -168,6 +168,7 @@ class _ConnectionFairy(object):
     """proxies a DBAPI connection object and provides return-on-dereference support"""
     def __init__(self, pool):
         self._threadfairy = _ThreadFairy(self)
+        self.cursors = weakref.WeakKeyDictionary()
         self.__pool = pool
         self.__counter = 0
         try:
@@ -182,6 +183,7 @@ class _ConnectionFairy(object):
     def invalidate(self):
         self._connection_record.invalidate()
         self.connection = None
+        self.cursors = None
         self._close()
     def cursor(self, *args, **kwargs):
         try:
@@ -196,6 +198,9 @@ class _ConnectionFairy(object):
             raise "this connection is closed"
         self.__counter +=1
         return self    
+    def close_open_cursors(self):
+        for c in list(self.cursors):
+            c.close()
     def close(self):
         self.__counter -=1
         if self.__counter == 0:
@@ -203,6 +208,8 @@ class _ConnectionFairy(object):
     def __del__(self):
         self._close()
     def _close(self):
+        if self.cursors is not None and len(self.cursors):
+            raise exceptions.InvalidRequestError("This connection still has %d open cursors" % len(self.cursors))
         if self.connection is not None:
             try:
                 self.connection.rollback()
@@ -219,7 +226,12 @@ class _ConnectionFairy(object):
 class _CursorFairy(object):
     def __init__(self, parent, cursor):
         self.__parent = parent
+        self.__parent.cursors[self]=True
         self.cursor = cursor
+    def close(self):
+        if self in self.__parent.cursors:
+            del self.__parent.cursors[self]
+            self.cursor.close()
     def __getattr__(self, key):
         return getattr(self.cursor, key)