Browse Source

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.
pull/27392/head
Erlend Egeberg Aasland 5 years ago
committed by GitHub
parent
commit
890e22957d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      Modules/_sqlite/connection.c
  2. 3
      Modules/_sqlite/connection.h

41
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;

3
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;

Loading…
Cancel
Save