]> granicus.if.org Git - python/commitdiff
bpo-9303: Migrate sqlite3 module to _v2 API to enhance performance (#359)
authorAviv Palivoda <palaviv@gmail.com>
Fri, 3 Mar 2017 10:58:17 +0000 (12:58 +0200)
committerBerker Peksag <berker.peksag@gmail.com>
Fri, 3 Mar 2017 10:58:17 +0000 (13:58 +0300)
Misc/NEWS
Modules/_sqlite/connection.c
Modules/_sqlite/cursor.c
Modules/_sqlite/statement.c
Modules/_sqlite/util.c
Modules/_sqlite/util.h

index 583d35ec4a16a1970a8a6adc18df83786b00b57d..e515e6a32962e74964f373c7b985dc4170895509 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -259,6 +259,8 @@ Extension Modules
 Library
 -------
 
+- bpo-9303: Migrate sqlite3 module to _v2 API.  Patch by Aviv Palivoda.
+
 - bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback 
   implemented in C.
 
index 37b45f330b349381f4d29e086fbaa34563221ba5..774399933ee73ae3fbc8158f6c9e127a2837d796 100644 (file)
@@ -118,6 +118,8 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
         return -1;
     }
     Py_BEGIN_ALLOW_THREADS
+    /* No need to use sqlite3_open_v2 as sqlite3_open(filename, db) is the
+       same as sqlite3_open_v2(filename, db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL). */
     rc = sqlite3_open(database, &self->db);
 #endif
     Py_END_ALLOW_THREADS
@@ -241,7 +243,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
     /* Clean up if user has not called .close() explicitly. */
     if (self->db) {
         Py_BEGIN_ALLOW_THREADS
-        sqlite3_close(self->db);
+        SQLITE3_CLOSE(self->db);
         Py_END_ALLOW_THREADS
     }
 
@@ -334,7 +336,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
 
     if (self->db) {
         Py_BEGIN_ALLOW_THREADS
-        rc = sqlite3_close(self->db);
+        rc = SQLITE3_CLOSE(self->db);
         Py_END_ALLOW_THREADS
 
         if (rc != SQLITE_OK) {
@@ -375,7 +377,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
     sqlite3_stmt* statement;
 
     Py_BEGIN_ALLOW_THREADS
-    rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail);
+    rc = SQLITE3_PREPARE(self->db, self->begin_statement, -1, &statement, &tail);
     Py_END_ALLOW_THREADS
 
     if (rc != SQLITE_OK) {
@@ -417,7 +419,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
     if (!sqlite3_get_autocommit(self->db)) {
 
         Py_BEGIN_ALLOW_THREADS
-        rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
+        rc = SQLITE3_PREPARE(self->db, "COMMIT", -1, &statement, &tail);
         Py_END_ALLOW_THREADS
         if (rc != SQLITE_OK) {
             _pysqlite_seterror(self->db, NULL);
@@ -460,7 +462,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
         pysqlite_do_all_statements(self, ACTION_RESET, 1);
 
         Py_BEGIN_ALLOW_THREADS
-        rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
+        rc = SQLITE3_PREPARE(self->db, "ROLLBACK", -1, &statement, &tail);
         Py_END_ALLOW_THREADS
         if (rc != SQLITE_OK) {
             _pysqlite_seterror(self->db, NULL);
index 8341fb8480172c946bfdc62c0c52dcac402d221f..ba6e52db568367b2e38dba6d1d95d88b8a0b1dc6 100644 (file)
@@ -548,8 +548,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
                 /* If it worked, let's get out of the loop */
                 break;
             }
+#if SQLITE_VERSION_NUMBER < 3003009
             /* Something went wrong.  Re-set the statement and try again. */
             rc = pysqlite_statement_reset(self->statement);
+#endif
             if (rc == SQLITE_SCHEMA) {
                 /* If this was a result of the schema changing, let's try
                    again. */
@@ -706,7 +708,7 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
 
     while (1) {
         Py_BEGIN_ALLOW_THREADS
-        rc = sqlite3_prepare(self->connection->db,
+        rc = SQLITE3_PREPARE(self->connection->db,
                              script_cstr,
                              -1,
                              &statement,
index 27b2654b103419cc18c2a14eb94e8fa1fc752dd8..bc0d9401d0fe344f0ddd74bd4d0a4121f856c1fb 100644 (file)
@@ -93,7 +93,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
     }
 
     Py_BEGIN_ALLOW_THREADS
-    rc = sqlite3_prepare(connection->db,
+    rc = SQLITE3_PREPARE(connection->db,
                          sql_cstr,
                          -1,
                          &self->st,
@@ -334,7 +334,7 @@ int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params)
     }
 
     Py_BEGIN_ALLOW_THREADS
-    rc = sqlite3_prepare(self->db,
+    rc = SQLITE3_PREPARE(self->db,
                          sql_cstr,
                          -1,
                          &new_st,
index 351b1b47a44d439c131676de2ccc4c3bb0d7aef5..b371aed99dbe4dbbf37ad4ef1ffeae999147d2a2 100644 (file)
@@ -49,10 +49,13 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
 {
     int errorcode;
 
-    /* SQLite often doesn't report anything useful, unless you reset the statement first */
+#if SQLITE_VERSION_NUMBER < 3003009
+    /* SQLite often doesn't report anything useful, unless you reset the statement first.
+       When using sqlite3_prepare_v2 this is not needed. */
     if (st != NULL) {
         (void)sqlite3_reset(st);
     }
+#endif
 
     errorcode = sqlite3_errcode(db);
 
index 88ea90689d518c0e92f771b635acb9e763c822fa..9106fcaf54c6b3338f56397824f33cc5bdc470b3 100644 (file)
@@ -39,4 +39,16 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
 PyObject * _pysqlite_long_from_int64(sqlite_int64 value);
 sqlite_int64 _pysqlite_long_as_int64(PyObject * value);
 
+#if SQLITE_VERSION_NUMBER >= 3003009
+#define SQLITE3_PREPARE sqlite3_prepare_v2
+#else
+#define SQLITE3_PREPARE sqlite3_prepare
+#endif
+
+#if SQLITE_VERSION_NUMBER >= 3007014
+#define SQLITE3_CLOSE sqlite3_close_v2
+#else
+#define SQLITE3_CLOSE sqlite3_close
+#endif
+
 #endif