mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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.
This commit is contained in:
parent
2e41df4d60
commit
890e22957d
2 changed files with 19 additions and 29 deletions
|
@ -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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (callable != Py_None) {
|
||||
if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1)
|
||||
goto finally;
|
||||
} else {
|
||||
if (PyDict_DelItem(self->collations, uppercase_name) == -1)
|
||||
goto finally;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue