changeset: 103684:80946f95e88a parent: 103682:3308f06726e9 user: Berker Peksag date: Mon Sep 12 07:16:43 2016 +0300 files: Misc/NEWS Modules/_sqlite/connection.c Modules/_sqlite/connection.h Modules/_sqlite/cursor.c description: Issue #28037: Use sqlite3_get_autocommit() instead of setting Connection->inTransaction manually Patch adapted from https://github.com/ghaering/pysqlite/commit/9b79188edbc50faa24dc178afe24a10454f3fcad diff -r 3308f06726e9 -r 80946f95e88a Misc/NEWS --- a/Misc/NEWS Sun Sep 11 20:19:35 2016 -0700 +++ b/Misc/NEWS Mon Sep 12 07:16:43 2016 +0300 @@ -143,6 +143,9 @@ 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 -r 3308f06726e9 -r 80946f95e88a Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c Sun Sep 11 20:19:35 2016 -0700 +++ b/Modules/_sqlite/connection.c Mon Sep 12 07:16:43 2016 +0300 @@ -165,7 +165,6 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ 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 @@ } 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_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 @@ Py_DECREF(res); self->begin_statement = NULL; - self->inTransaction = 0; } else { const char * const *candidate; PyObject *uppercase_level; @@ -1606,6 +1609,7 @@ 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 @@ {"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 -r 3308f06726e9 -r 80946f95e88a Modules/_sqlite/connection.h --- a/Modules/_sqlite/connection.h Sun Sep 11 20:19:35 2016 -0700 +++ b/Modules/_sqlite/connection.h Mon Sep 12 07:16:43 2016 +0300 @@ -37,10 +37,6 @@ 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 -r 3308f06726e9 -r 80946f95e88a Modules/_sqlite/cursor.c --- a/Modules/_sqlite/cursor.c Sun Sep 11 20:19:35 2016 -0700 +++ b/Modules/_sqlite/cursor.c Mon Sep 12 07:16:43 2016 +0300 @@ -644,15 +644,6 @@ } 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);