]> granicus.if.org Git - python/commitdiff
#8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute.
authorR. David Murray <rdmurray@bitdance.com>
Tue, 1 Jun 2010 01:32:12 +0000 (01:32 +0000)
committerR. David Murray <rdmurray@bitdance.com>
Tue, 1 Jun 2010 01:32:12 +0000 (01:32 +0000)
Patch by R. David Murray, unit tests by Shashwat Anand.

Doc/library/sqlite3.rst
Doc/whatsnew/3.2.rst
Lib/sqlite3/test/dbapi.py
Misc/ACKS
Misc/NEWS
Modules/_sqlite/connection.c

index ad6a641b977479ea386f5e05ae5f0baef738584c..3db5116573292fe08f062e7a09ed73cbec766b81 100644 (file)
@@ -227,6 +227,13 @@ Connection Objects
    one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section
    :ref:`sqlite3-controlling-transactions` for a more detailed explanation.
 
+.. attribute:: Connection.in_transaction
+
+   .. versionadded:: 3.2
+
+   :cont:`True` if a transaction is active (there are uncommitted changes),
+   :const:`False` otherwise.  Read-only attribute.
+
 
 .. method:: Connection.cursor([cursorClass])
 
@@ -806,7 +813,8 @@ So if you are within a transaction and issue a command like ``CREATE TABLE
 before executing that command. There are two reasons for doing that. The first
 is that some of these commands don't work within transactions. The other reason
 is that sqlite3 needs to keep track of the transaction state (if a transaction
-is active or not).
+is active or not).  The current transaction state is exposed through the
+:attr:`Connection.in_transaction` attribute of the connection object.
 
 You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes
 (or none at all) via the *isolation_level* parameter to the :func:`connect`
index e61ad44f5f69c02c6eebe271ff1318a4b20b2885..265f9282e5713dea9c3f43353cea449236dd6115 100644 (file)
@@ -100,6 +100,18 @@ New, Improved, and Deprecated Modules
 
   (Contributed by Tarek Ziade.)
 
+* The *sqlite3* module has some new features:
+
+  * XXX *enable_load_extension*
+
+  * XXX *load_extension*
+
+  * New :class:`~sqlite3.Connection` attribute
+    :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there
+    are uncommitted changes, and :const:`False` otherwise.  (Contributed
+    by R. David Murray and Shashwat Anand, :issue:`8845`.)
+
+
 Multi-threading
 ===============
 
index ced6679140e93bb26342808a65ff09f4782b352f..51253d00247776df33dcca771279241a845df5d6 100644 (file)
@@ -84,6 +84,7 @@ class ModuleTests(unittest.TestCase):
                         "NotSupportedError is not a subclass of DatabaseError")
 
 class ConnectionTests(unittest.TestCase):
+
     def setUp(self):
         self.cx = sqlite.connect(":memory:")
         cu = self.cx.cursor()
@@ -140,6 +141,28 @@ class ConnectionTests(unittest.TestCase):
         self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
         self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
 
+    def CheckInTransaction(self):
+        # Can't use db from setUp because we want to test initial state.
+        cx = sqlite.connect(":memory:")
+        cu = cx.cursor()
+        self.assertEqual(cx.in_transaction, False)
+        cu.execute("create table transactiontest(id integer primary key, name text)")
+        self.assertEqual(cx.in_transaction, False)
+        cu.execute("insert into transactiontest(name) values (?)", ("foo",))
+        self.assertEqual(cx.in_transaction, True)
+        cu.execute("select name from transactiontest where name=?", ["foo"])
+        row = cu.fetchone()
+        self.assertEqual(cx.in_transaction, True)
+        cx.commit()
+        self.assertEqual(cx.in_transaction, False)
+        cu.execute("select name from transactiontest where name=?", ["foo"])
+        row = cu.fetchone()
+        self.assertEqual(cx.in_transaction, False)
+
+    def CheckInTransactionRO(self):
+        with self.assertRaises(AttributeError):
+            self.cx.in_transaction = True
+
 class CursorTests(unittest.TestCase):
     def setUp(self):
         self.cx = sqlite.connect(":memory:")
index 50919413d97cf416e5dce1bebe3c57900dce3d25..b75ff6ce36cdc8fcd66df7729870f128fb669cc4 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -19,6 +19,7 @@ Billy G. Allie
 Kevin Altis
 Joe Amenta
 Mark Anacker
+Shashwat Anand
 Anders Andersen
 John Anderson
 Erik Andersén
index a65de665cc17c823d70965bb44b6d8a01ebb73be..68f36fcc93099b2f1f084d652c9c9be254cfe153 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -398,6 +398,9 @@ C-API
 Library
 -------
 
+- Issue #8845: sqlite3 Connection objects now have a read-only in_transaction
+  attribute that is True iff there are uncommitted changes.
+
 - Issue #1289118: datetime.timedelta objects can now be multiplied by float
   and divided by float and int objects.  Results are rounded to the nearest
   multiple of timedelta.resolution with ties resolved using round-half-to-even
index 184bdeef93aac68e9be99eae2d37f8b8b209b422..8bfc9ba65681ecd1c32b0d266a4a25635d2e8840 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "cache.h"
 #include "module.h"
+#include "structmember.h"
 #include "connection.h"
 #include "statement.h"
 #include "cursor.h"
@@ -1551,6 +1552,7 @@ static struct PyMemberDef connection_members[] =
     {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY},
     {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)},
     {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)},
+    {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY},
     {NULL}
 };