Skip to content

Commit 86a6705

Browse files
palavivberkerpeksag
authored andcommitted
bpo-9303: Migrate sqlite3 module to _v2 API to enhance performance (#359)
1 parent 15aa4c8 commit 86a6705

File tree

6 files changed

+30
-9
lines changed

6 files changed

+30
-9
lines changed

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ Extension Modules
259259
Library
260260
-------
261261

262+
- bpo-9303: Migrate sqlite3 module to _v2 API. Patch by Aviv Palivoda.
263+
262264
- bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback
263265
implemented in C.
264266

Modules/_sqlite/connection.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
118118
return -1;
119119
}
120120
Py_BEGIN_ALLOW_THREADS
121+
/* No need to use sqlite3_open_v2 as sqlite3_open(filename, db) is the
122+
same as sqlite3_open_v2(filename, db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL). */
121123
rc = sqlite3_open(database, &self->db);
122124
#endif
123125
Py_END_ALLOW_THREADS
@@ -241,7 +243,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
241243
/* Clean up if user has not called .close() explicitly. */
242244
if (self->db) {
243245
Py_BEGIN_ALLOW_THREADS
244-
sqlite3_close(self->db);
246+
SQLITE3_CLOSE(self->db);
245247
Py_END_ALLOW_THREADS
246248
}
247249

@@ -334,7 +336,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
334336

335337
if (self->db) {
336338
Py_BEGIN_ALLOW_THREADS
337-
rc = sqlite3_close(self->db);
339+
rc = SQLITE3_CLOSE(self->db);
338340
Py_END_ALLOW_THREADS
339341

340342
if (rc != SQLITE_OK) {
@@ -375,7 +377,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
375377
sqlite3_stmt* statement;
376378

377379
Py_BEGIN_ALLOW_THREADS
378-
rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail);
380+
rc = SQLITE3_PREPARE(self->db, self->begin_statement, -1, &statement, &tail);
379381
Py_END_ALLOW_THREADS
380382

381383
if (rc != SQLITE_OK) {
@@ -417,7 +419,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
417419
if (!sqlite3_get_autocommit(self->db)) {
418420

419421
Py_BEGIN_ALLOW_THREADS
420-
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
422+
rc = SQLITE3_PREPARE(self->db, "COMMIT", -1, &statement, &tail);
421423
Py_END_ALLOW_THREADS
422424
if (rc != SQLITE_OK) {
423425
_pysqlite_seterror(self->db, NULL);
@@ -460,7 +462,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
460462
pysqlite_do_all_statements(self, ACTION_RESET, 1);
461463

462464
Py_BEGIN_ALLOW_THREADS
463-
rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
465+
rc = SQLITE3_PREPARE(self->db, "ROLLBACK", -1, &statement, &tail);
464466
Py_END_ALLOW_THREADS
465467
if (rc != SQLITE_OK) {
466468
_pysqlite_seterror(self->db, NULL);

Modules/_sqlite/cursor.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
548548
/* If it worked, let's get out of the loop */
549549
break;
550550
}
551+
#if SQLITE_VERSION_NUMBER < 3003009
551552
/* Something went wrong. Re-set the statement and try again. */
552553
rc = pysqlite_statement_reset(self->statement);
554+
#endif
553555
if (rc == SQLITE_SCHEMA) {
554556
/* If this was a result of the schema changing, let's try
555557
again. */
@@ -706,7 +708,7 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
706708

707709
while (1) {
708710
Py_BEGIN_ALLOW_THREADS
709-
rc = sqlite3_prepare(self->connection->db,
711+
rc = SQLITE3_PREPARE(self->connection->db,
710712
script_cstr,
711713
-1,
712714
&statement,

Modules/_sqlite/statement.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
9393
}
9494

9595
Py_BEGIN_ALLOW_THREADS
96-
rc = sqlite3_prepare(connection->db,
96+
rc = SQLITE3_PREPARE(connection->db,
9797
sql_cstr,
9898
-1,
9999
&self->st,
@@ -334,7 +334,7 @@ int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params)
334334
}
335335

336336
Py_BEGIN_ALLOW_THREADS
337-
rc = sqlite3_prepare(self->db,
337+
rc = SQLITE3_PREPARE(self->db,
338338
sql_cstr,
339339
-1,
340340
&new_st,

Modules/_sqlite/util.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,13 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
4949
{
5050
int errorcode;
5151

52-
/* SQLite often doesn't report anything useful, unless you reset the statement first */
52+
#if SQLITE_VERSION_NUMBER < 3003009
53+
/* SQLite often doesn't report anything useful, unless you reset the statement first.
54+
When using sqlite3_prepare_v2 this is not needed. */
5355
if (st != NULL) {
5456
(void)sqlite3_reset(st);
5557
}
58+
#endif
5659

5760
errorcode = sqlite3_errcode(db);
5861

Modules/_sqlite/util.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,16 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
3939
PyObject * _pysqlite_long_from_int64(sqlite_int64 value);
4040
sqlite_int64 _pysqlite_long_as_int64(PyObject * value);
4141

42+
#if SQLITE_VERSION_NUMBER >= 3003009
43+
#define SQLITE3_PREPARE sqlite3_prepare_v2
44+
#else
45+
#define SQLITE3_PREPARE sqlite3_prepare
46+
#endif
47+
48+
#if SQLITE_VERSION_NUMBER >= 3007014
49+
#define SQLITE3_CLOSE sqlite3_close_v2
50+
#else
51+
#define SQLITE3_CLOSE sqlite3_close
52+
#endif
53+
4254
#endif

0 commit comments

Comments
 (0)