]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
_ConnectionRecord gains a .properties collection, with contents scoped to
authorJason Kirtland <jek@discorporate.us>
Mon, 23 Jul 2007 20:32:19 +0000 (20:32 +0000)
committerJason Kirtland <jek@discorporate.us>
Mon, 23 Jul 2007 20:32:19 +0000 (20:32 +0000)
the lifetime of the underlying DBAPI connection.  Accessors on Connections and fairies.

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

diff --git a/CHANGES b/CHANGES
index f6403612f03f84deed18a6e444f5c7315df4b96a..f68b80c53226b1de5793df48246996dbb3d86dcb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
   - better quoting of identifiers when manipulating schemas
   - standardized the behavior for table reflection where types can't be located;
     NullType is substituted instead, warning is raised.
+- engines
+  - Connections gain a .properties collection, with contents scoped to the
+    lifetime of the underlying DBAPI connection
 - extensions
   - proxyengine is temporarily removed, pending an actually working
     replacement.
index 5bc72db8acc1d7f8fc945d2d30cc6a9dbb0751f0..796df1a5c1ab89dac97469315f12957c4b3ef58e 100644 (file)
@@ -518,6 +518,8 @@ class Connection(Connectable):
     dialect = property(lambda s:s.__engine.dialect, doc="Dialect used by this Connection.")
     connection = property(_get_connection, doc="The underlying DBAPI connection managed by this Connection.")
     should_close_with_result = property(lambda s:s.__close_with_result, doc="Indicates if this Connection should be closed when a corresponding ResultProxy is closed; this is essentially an auto-release mode.")
+    properties = property(lambda s: s._get_connection().properties,
+                          doc="A set of per-DBAPI connection properties.")
 
     def connect(self):
         """connect() is implemented to return self so that an incoming Engine or Connection object can be treated similarly."""
index 72325448e610636689d2f3fc0fe0318fb219f6fe..f86e14ab1ef3e1aea4345d50624b3bf37977b2bf 100644 (file)
@@ -190,6 +190,7 @@ class _ConnectionRecord(object):
     def __init__(self, pool):
         self.__pool = pool
         self.connection = self.__connect()
+        self.properties = {}
 
     def close(self):
         if self.connection is not None:
@@ -207,10 +208,12 @@ class _ConnectionRecord(object):
     def get_connection(self):
         if self.connection is None:
             self.connection = self.__connect()
+            self.properties.clear()
         elif (self.__pool._recycle > -1 and time.time() - self.starttime > self.__pool._recycle):
             self.__pool.log("Connection %s exceeded timeout; recycling" % repr(self.connection))
             self.__close()
             self.connection = self.__connect()
+            self.properties.clear()
         return self.connection
 
     def __close(self):
@@ -257,6 +260,21 @@ class _ConnectionFairy(object):
     _logger = property(lambda self: self._pool.logger)
     
     is_valid = property(lambda self:self.connection is not None)
+
+    def _get_properties(self):
+        """A property collection unique to this DBAPI connection."""
+        
+        try:
+            return self._connection_record.properties
+        except AttributeError:
+            if self.connection is None:
+                raise exceptions.InvalidRequestError("This connection is closed")
+            try:
+                return self._detatched_properties
+            except AttributeError:
+                self._detatched_properties = value = {}
+                return value
+    properties = property(_get_properties)
     
     def invalidate(self, e=None):
         """Mark this connection as invalidated.
@@ -301,6 +319,8 @@ class _ConnectionFairy(object):
         if self._connection_record is not None:
             self._connection_record.connection = None        
             self._pool.do_return_conn(self._connection_record)
+            self._detatched_properties = \
+              self._connection_record.properties.copy()
             self._connection_record = None
 
     def close_open_cursors(self):
index 3bb25ec72a7fb11db44cfe80aa8c95d307a46d85..364afa9d750d461eaf12560745d8537a7842e35b 100644 (file)
@@ -351,6 +351,35 @@ class PoolTest(PersistTest):
                     c2 = None
                     c1 = None
                 self.assert_(p.checkedout() == 0)
+
+    def test_properties(self):
+        dbapi = MockDBAPI()
+        p = pool.QueuePool(creator=lambda: dbapi.connect('foo.db'),
+                           pool_size=1, max_overflow=0)
+
+        c = p.connect()
+        self.assert_(not c.properties)
+        self.assert_(c.properties is c._connection_record.properties)
+
+        c.properties['foo'] = 'bar'
+        c.close()
+        del c
+
+        c = p.connect()
+        self.assert_('foo' in c.properties)
+
+        c.invalidate()
+        c = p.connect()
+        self.assert_('foo' not in c.properties)
+
+        c.properties['foo2'] = 'bar2'
+        c.detach()
+        self.assert_('foo2' in c.properties)
+
+        c2 = p.connect()
+        self.assert_(c.connection is not c2.connection)
+        self.assert_(not c2.properties)
+        self.assert_('foo2' in c.properties)
             
     def tearDown(self):
        pool.clear_managers()