#8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute.
Patch by R. David Murray, unit tests by Shashwat Anand.
This commit is contained in:
parent
bcb8d3a0a5
commit
d35251dc19
|
@ -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`
|
||||
|
|
|
@ -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
|
||||
===============
|
||||
|
||||
|
|
|
@ -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:")
|
||||
|
|
|
@ -19,6 +19,7 @@ Billy G. Allie
|
|||
Kevin Altis
|
||||
Joe Amenta
|
||||
Mark Anacker
|
||||
Shashwat Anand
|
||||
Anders Andersen
|
||||
John Anderson
|
||||
Erik Andersén
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue