[Python-checkins] cpython: Issue #28037: Use sqlite3_get_autocommit() instead of setting

berker.peksag python-checkins at python.org
Mon Sep 12 00:16:05 EDT 2016


https://hg.python.org/cpython/rev/80946f95e88a
changeset:   103684:80946f95e88a
parent:      103682:3308f06726e9
user:        Berker Peksag <berker.peksag at gmail.com>
date:        Mon Sep 12 07:16:43 2016 +0300
summary:
  Issue #28037: Use sqlite3_get_autocommit() instead of setting Connection->inTransaction manually

Patch adapted from https://github.com/ghaering/pysqlite/commit/9b79188edbc50faa24dc178afe24a10454f3fcad

files:
  Misc/NEWS                    |   3 ++
  Modules/_sqlite/connection.c |  31 +++++++++++++----------
  Modules/_sqlite/connection.h |   4 ---
  Modules/_sqlite/cursor.c     |   9 ------
  4 files changed, 20 insertions(+), 27 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -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 --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h
--- a/Modules/_sqlite/connection.h
+++ b/Modules/_sqlite/connection.h
@@ -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 --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -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);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list