Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/library/sqlite3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ Module functions and constants
.. versionchanged:: 3.4
Added the *uri* parameter.

.. versionchanged:: 3.7
When *cached_statements* is set to 0 there is no statement cache.


.. function:: register_converter(typename, callable)

Expand Down
2 changes: 2 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins
-----------------

- bpo-30271: sqlite3 statement cache is optional. Patch by Aviv Palivoda.

- bpo-12414: sys.getsizeof() on a code object now returns the sizes
which includes the code struct and sizes of objects which it references.
Patch by Dong-hee Na.
Expand Down
8 changes: 5 additions & 3 deletions Modules/_sqlite/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs)
return -1;
}

/* minimum cache size is 5 entries */
if (size < 5) {
size = 5;
/* minimum cache size is 1 entry */
if (size < 1) {
PyErr_SetString(PyExc_ValueError,
"Minimum cache size is 1");
return -1;
}
self->size = size;
self->first = NULL;
Expand Down
27 changes: 15 additions & 12 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,18 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
}
Py_DECREF(isolation_level);

self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements);
if (PyErr_Occurred()) {
return -1;
if (cached_statements != 0) {
self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements);
if (PyErr_Occurred()) {
return -1;
}
/* By default, the Cache class INCREFs the factory in its initializer, and
* decrefs it in its deallocator method. Since this would create a circular
* reference here, we're breaking it by decrementing self, and telling the
* cache class to not decref the factory (self) in its deallocator.
*/
self->statement_cache->decref_factory = 0;
Py_DECREF(self);
}

self->created_statements = 0;
Expand All @@ -159,14 +168,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
return -1;
}

/* By default, the Cache class INCREFs the factory in its initializer, and
* decrefs it in its deallocator method. Since this would create a circular
* reference here, we're breaking it by decrementing self, and telling the
* cache class to not decref the factory (self) in its deallocator.
*/
self->statement_cache->decref_factory = 0;
Py_DECREF(self);

self->detect_types = detect_types;
self->timeout = timeout;
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
Expand Down Expand Up @@ -238,7 +239,9 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset

void pysqlite_connection_dealloc(pysqlite_Connection* self)
{
Py_XDECREF(self->statement_cache);
if (self->statement_cache) {
Py_XDECREF(self->statement_cache);
}

/* Clean up if user has not called .close() explicitly. */
if (self->db) {
Expand Down
13 changes: 10 additions & 3 deletions Modules/_sqlite/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,16 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
(void)pysqlite_statement_reset(self->statement);
}

Py_XSETREF(self->statement,
(pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args));
Py_DECREF(func_args);
if (self->connection->statement_cache) {
/* We look in statment cache */
Py_XSETREF(self->statement,
(pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args));
Py_DECREF(func_args);
} else {
/* We don't have statment cache */
Py_XSETREF(self->statement,
(pysqlite_Statement *)PyObject_CallFunction((PyObject*)self->connection, "O", func_args));
}

if (!self->statement) {
goto error;
Expand Down