summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBerker Peksag <berker.peksag@gmail.com>2016-09-12 04:16:43 (GMT)
committerBerker Peksag <berker.peksag@gmail.com>2016-09-12 04:16:43 (GMT)
commit59da4b324f08247d389a4c89e1e84243f41c489f (patch)
treef82798f28c4b1e3a157a0375c31579b871491408
parente7da2f8380fbd92d5978e9fb8ce317ecfd17d12e (diff)
downloadcpython-59da4b324f08247d389a4c89e1e84243f41c489f.zip
cpython-59da4b324f08247d389a4c89e1e84243f41c489f.tar.gz
cpython-59da4b324f08247d389a4c89e1e84243f41c489f.tar.bz2
Issue #28037: Use sqlite3_get_autocommit() instead of setting Connection->inTransaction manually
Patch adapted from https://github.com/ghaering/pysqlite/commit/9b79188edbc50faa24dc178afe24a10454f3fcad
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_sqlite/connection.c31
-rw-r--r--Modules/_sqlite/connection.h4
-rw-r--r--Modules/_sqlite/cursor.c9
4 files changed, 20 insertions, 27 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 35f1d65..1c253b6 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -143,6 +143,9 @@ Core and Builtins
Library
-------
+- Issue #28037: Use sqlite3_get_autocommit() instead of setting
+ Connection->inTransaction manually.
+
- Issue #25283: Attributes tm_gmtoff and tm_zone are now available on
all platforms in the return values of time.localtime() and
time.gmtime().
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index aca66fe..d29fafe 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -165,7 +165,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
self->statement_cache->decref_factory = 0;
Py_DECREF(self);
- self->inTransaction = 0;
self->detect_types = detect_types;
self->timeout = timeout;
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
@@ -385,9 +384,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
}
rc = pysqlite_step(statement, self);
- if (rc == SQLITE_DONE) {
- self->inTransaction = 1;
- } else {
+ if (rc != SQLITE_DONE) {
_pysqlite_seterror(self->db, statement);
}
@@ -418,7 +415,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
return NULL;
}
- if (self->inTransaction) {
+ if (!sqlite3_get_autocommit(self->db)) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
@@ -429,9 +426,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
}
rc = pysqlite_step(statement, self);
- if (rc == SQLITE_DONE) {
- self->inTransaction = 0;
- } else {
+ if (rc != SQLITE_DONE) {
_pysqlite_seterror(self->db, statement);
}
@@ -463,7 +458,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
return NULL;
}
- if (self->inTransaction) {
+ if (!sqlite3_get_autocommit(self->db)) {
pysqlite_do_all_statements(self, ACTION_RESET, 1);
Py_BEGIN_ALLOW_THREADS
@@ -475,9 +470,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
}
rc = pysqlite_step(statement, self);
- if (rc == SQLITE_DONE) {
- self->inTransaction = 0;
- } else {
+ if (rc != SQLITE_DONE) {
_pysqlite_seterror(self->db, statement);
}
@@ -1158,6 +1151,17 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self
}
}
+static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused)
+{
+ if (!pysqlite_check_connection(self)) {
+ return NULL;
+ }
+ if (!sqlite3_get_autocommit(self->db)) {
+ Py_RETURN_TRUE;
+ }
+ Py_RETURN_FALSE;
+}
+
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level)
{
if (isolation_level == Py_None) {
@@ -1168,7 +1172,6 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py
Py_DECREF(res);
self->begin_statement = NULL;
- self->inTransaction = 0;
} else {
const char * const *candidate;
PyObject *uppercase_level;
@@ -1606,6 +1609,7 @@ PyDoc_STR("SQLite database connection object.");
static PyGetSetDef connection_getset[] = {
{"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
{"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0},
+ {"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0},
{NULL}
};
@@ -1667,7 +1671,6 @@ 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}
};
diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h
index adbfb54..2860a0c 100644
--- a/Modules/_sqlite/connection.h
+++ b/Modules/_sqlite/connection.h
@@ -37,10 +37,6 @@ typedef struct
PyObject_HEAD
sqlite3* db;
- /* 1 if we are currently within a transaction, i. e. if a BEGIN has been
- * issued */
- char inTransaction;
-
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
* bitwise combination thereof makes sense */
int detect_types;
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index 020f931..c7169f6 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -644,15 +644,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
}
error:
- /* just to be sure (implicit ROLLBACKs with ON CONFLICT ROLLBACK/OR
- * ROLLBACK could have happened */
- #ifdef SQLITE_VERSION_NUMBER
- #if SQLITE_VERSION_NUMBER >= 3002002
- if (self->connection && self->connection->db)
- self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db);
- #endif
- #endif
-
Py_XDECREF(parameters);
Py_XDECREF(parameters_iter);
Py_XDECREF(parameters_list);