From: Mike Bayer Date: Mon, 29 May 2006 02:57:33 +0000 (+0000) Subject: connection more careful about checking if its closed before operations X-Git-Tag: rel_0_2_1~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c12b48b62e4f94a651eec634ca74a028e4b3d760;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git connection more careful about checking if its closed before operations small fix to table sort if no tables unit test tweaks --- diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index eaaae29d22..dafef729ae 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -177,8 +177,13 @@ class Connection(Connectable): self.__connection = connection or engine.raw_connection() self.__transaction = None self.__close_with_result = close_with_result + def _get_connection(self): + try: + return self.__connection + except AttributeError: + raise exceptions.InvalidRequestError("This Connection is closed") engine = property(lambda s:s.__engine, doc="The Engine with which this Connection is associated (read only)") - connection = property(lambda s:s.__connection, doc="The underlying DBAPI connection managed 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.") def _create_transaction(self, parent): return Transaction(self, parent) @@ -199,15 +204,15 @@ class Connection(Connectable): def _begin_impl(self): if self.__engine.echo: self.__engine.log("BEGIN") - self.__engine.dialect.do_begin(self.__connection) + self.__engine.dialect.do_begin(self.connection) def _rollback_impl(self): if self.__engine.echo: self.__engine.log("ROLLBACK") - self.__engine.dialect.do_rollback(self.__connection) + self.__engine.dialect.do_rollback(self.connection) def _commit_impl(self): if self.__engine.echo: self.__engine.log("COMMIT") - self.__engine.dialect.do_commit(self.__connection) + self.__engine.dialect.do_commit(self.connection) def _autocommit(self, statement): """when no Transaction is present, this is called after executions to provide "autocommit" behavior.""" # TODO: have the dialect determine if autocommit can be set on the connection directly without this @@ -218,9 +223,13 @@ class Connection(Connectable): if not self.in_transaction(): self._rollback_impl() def close(self): - if self.__connection is not None: - self.__connection.close() - self.__connection = None + try: + c = self.__connection + except AttributeError: + return + self.__connection.close() + self.__connection = None + del self.__connection def scalar(self, object, parameters=None, **kwargs): row = self.execute(object, parameters, **kwargs).fetchone() if row is not None: @@ -255,7 +264,7 @@ class Connection(Connectable): return self.execute_compiled(elem.compile(engine=self.__engine, parameters=param), *multiparams, **params) def execute_compiled(self, compiled, *multiparams, **params): """executes a sql.Compiled object.""" - cursor = self.__connection.cursor() + cursor = self.connection.cursor() parameters = [compiled.get_params(**m) for m in self._params_to_listofdicts(*multiparams, **params)] if len(parameters) == 1: parameters = parameters[0] @@ -295,7 +304,7 @@ class Connection(Connectable): callable_(self) def _execute_raw(self, statement, parameters=None, cursor=None, echo=None, context=None, **kwargs): if cursor is None: - cursor = self.__connection.cursor() + cursor = self.connection.cursor() try: if echo is True or self.__engine.echo is not False: self.__engine.log(statement) diff --git a/lib/sqlalchemy/sql_util.py b/lib/sqlalchemy/sql_util.py index e3170ebce3..0728bba47f 100644 --- a/lib/sqlalchemy/sql_util.py +++ b/lib/sqlalchemy/sql_util.py @@ -27,7 +27,8 @@ class TableCollection(object): seq.append( node.item ) for child in node.children: to_sequence( child ) - to_sequence( head ) + if head is not None: + to_sequence( head ) if reverse: sequence.reverse() return sequence diff --git a/test/defaults.py b/test/defaults.py index a271cbcb54..57b4388a19 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -165,4 +165,4 @@ class SequenceTest(PersistTest): cartitems.drop() if __name__ == "__main__": - unittest.main() + testbase.main() diff --git a/test/transaction.py b/test/transaction.py index d4f6dc8c46..408c9dc998 100644 --- a/test/transaction.py +++ b/test/transaction.py @@ -35,6 +35,7 @@ class TransactionTest(testbase.PersistTest): assert len(result.fetchall()) == 0 connection.close() + @testbase.unsupported('mysql') def testnesting(self): connection = testbase.db.connect() transaction = connection.begin() @@ -59,7 +60,8 @@ class AutoRollbackTest(testbase.PersistTest): def tearDownAll(self): metadata.drop_all(testbase.db) - + + @testbase.unsupported('sqlite') def testrollback_deadlock(self): """test that returning connections to the pool clears any object locks.""" conn1 = testbase.db.connect() @@ -144,6 +146,7 @@ class TLTransactionTest(testbase.PersistTest): finally: external_connection.close() + @testbase.unsupported('mysql') def testmixednesting(self): """tests nesting of transactions off the TLEngine directly inside of tranasctions off the connection from the TLEngine""" @@ -172,6 +175,7 @@ class TLTransactionTest(testbase.PersistTest): finally: external_connection.close() + @testbase.unsupported('mysql') def testmoremixednesting(self): """tests nesting of transactions off the connection from the TLEngine inside of tranasctions off thbe TLEngine directly."""