summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-07-27 13:54:20 (GMT)
committerGitHub <noreply@github.com>2021-07-27 13:54:20 (GMT)
commit890e22957d427ee994b85d62dfe4d5a7cbd34ec5 (patch)
treeb20dad5ada209730b02ba55722288c4049dacaf0 /Modules
parent2e41df4d60d71a2551b9605d07321f75cfb52adf (diff)
downloadcpython-890e22957d427ee994b85d62dfe4d5a7cbd34ec5.zip
cpython-890e22957d427ee994b85d62dfe4d5a7cbd34ec5.tar.gz
cpython-890e22957d427ee994b85d62dfe4d5a7cbd34ec5.tar.bz2
bpo-42064: Migrate to `sqlite3_create_collation_v2` (GH-27156)
This implies that SQLite now takes care of destroying the callback context (the PyObject callable it has been passed), so we can strip the collation dict from the connection object.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_sqlite/connection.c41
-rw-r--r--Modules/_sqlite/connection.h3
2 files changed, 17 insertions, 27 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 33d3d4c..af093c3 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -177,11 +177,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
self->function_pinboard_progress_handler = NULL;
self->function_pinboard_authorizer_cb = NULL;
- Py_XSETREF(self->collations, PyDict_New());
- if (!self->collations) {
- return -1;
- }
-
pysqlite_state *state = pysqlite_get_state(NULL);
self->Warning = state->Warning;
self->Error = state->Error;
@@ -249,7 +244,6 @@ connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg)
Py_VISIT(self->function_pinboard_trace_callback);
Py_VISIT(self->function_pinboard_progress_handler);
Py_VISIT(self->function_pinboard_authorizer_cb);
- Py_VISIT(self->collations);
return 0;
}
@@ -265,7 +259,6 @@ connection_clear(pysqlite_Connection *self)
Py_CLEAR(self->function_pinboard_trace_callback);
Py_CLEAR(self->function_pinboard_progress_handler);
Py_CLEAR(self->function_pinboard_authorizer_cb);
- Py_CLEAR(self->collations);
return 0;
}
@@ -1780,29 +1773,29 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
if (!uppercase_name_str)
goto finally;
- if (callable != Py_None && !PyCallable_Check(callable)) {
- PyErr_SetString(PyExc_TypeError, "parameter must be callable");
- goto finally;
+ int flags = SQLITE_UTF8;
+ if (callable == Py_None) {
+ rc = sqlite3_create_collation_v2(self->db, uppercase_name_str, flags,
+ NULL, NULL, NULL);
}
-
- if (callable != Py_None) {
- if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1)
- goto finally;
- } else {
- if (PyDict_DelItem(self->collations, uppercase_name) == -1)
+ else {
+ if (!PyCallable_Check(callable)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
goto finally;
+ }
+ rc = sqlite3_create_collation_v2(self->db, uppercase_name_str, flags,
+ Py_NewRef(callable),
+ &pysqlite_collation_callback,
+ &_destructor);
}
- rc = sqlite3_create_collation(self->db,
- uppercase_name_str,
- SQLITE_UTF8,
- (callable != Py_None) ? callable : NULL,
- (callable != Py_None) ? pysqlite_collation_callback : NULL);
if (rc != SQLITE_OK) {
+ /* Unlike other sqlite3_* functions, the destructor callback is _not_
+ * called if sqlite3_create_collation_v2() fails, so we have to free
+ * the context before returning.
+ */
if (callable != Py_None) {
- if (PyDict_DelItem(self->collations, uppercase_name) < 0) {
- PyErr_Clear();
- }
+ Py_DECREF(callable);
}
_pysqlite_seterror(self->db);
goto finally;
diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h
index 5e7e7e5..50c2015 100644
--- a/Modules/_sqlite/connection.h
+++ b/Modules/_sqlite/connection.h
@@ -82,9 +82,6 @@ typedef struct
PyObject* function_pinboard_progress_handler;
PyObject* function_pinboard_authorizer_cb;
- /* a dictionary of registered collation name => collation callable mappings */
- PyObject* collations;
-
/* Exception objects: borrowed refs. */
PyObject* Warning;
PyObject* Error;