mirror of https://github.com/python/cpython
bpo-42064: Optimise `sqlite3` state access, part 1 (GH-27273)
Prepare for module state: - Add "get state by defining class" and "get state by module def" stubs - Add AC defining class when needed - Add state pointer to connection context - Pass state as argument to utility functions Automerge-Triggered-By: GH:encukou
This commit is contained in:
parent
47fd4726a2
commit
d542742128
|
@ -249,14 +249,25 @@ PyDoc_STRVAR(pysqlite_cursor_close__doc__,
|
|||
"Closes the cursor.");
|
||||
|
||||
#define PYSQLITE_CURSOR_CLOSE_METHODDEF \
|
||||
{"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, pysqlite_cursor_close__doc__},
|
||||
{"close", (PyCFunction)(void(*)(void))pysqlite_cursor_close, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_close__doc__},
|
||||
|
||||
static PyObject *
|
||||
pysqlite_cursor_close_impl(pysqlite_Cursor *self);
|
||||
pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls);
|
||||
|
||||
static PyObject *
|
||||
pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored))
|
||||
pysqlite_cursor_close(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
return pysqlite_cursor_close_impl(self);
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = { NULL};
|
||||
static _PyArg_Parser _parser = {":close", _keywords, 0};
|
||||
|
||||
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser
|
||||
)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = pysqlite_cursor_close_impl(self, cls);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=8f70eac5f8aa8d97 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=7b216aba2439f5cf input=a9049054013a1b77]*/
|
||||
|
|
|
@ -66,8 +66,8 @@ new_statement_cache(pysqlite_Connection *self, int maxsize)
|
|||
if (args[0] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
PyObject *inner = PyObject_Vectorcall(state->lru_cache, args, 1, NULL);
|
||||
PyObject *lru_cache = self->state->lru_cache;
|
||||
PyObject *inner = PyObject_Vectorcall(lru_cache, args, 1, NULL);
|
||||
Py_DECREF(args[0]);
|
||||
if (inner == NULL) {
|
||||
return NULL;
|
||||
|
@ -106,6 +106,9 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
|
|||
return -1;
|
||||
}
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self));
|
||||
self->state = state;
|
||||
|
||||
const char *database = PyBytes_AsString(database_obj);
|
||||
|
||||
self->initialized = 1;
|
||||
|
@ -131,7 +134,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
|
|||
Py_DECREF(database_obj); // needed bco. the AC FSConverter
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(state, self->db);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -177,7 +180,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
|
|||
self->function_pinboard_progress_handler = NULL;
|
||||
self->function_pinboard_authorizer_cb = NULL;
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
self->Warning = state->Warning;
|
||||
self->Error = state->Error;
|
||||
self->InterfaceError = state->InterfaceError;
|
||||
|
@ -330,15 +332,14 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (factory == NULL) {
|
||||
factory = (PyObject *)state->CursorType;
|
||||
factory = (PyObject *)self->state->CursorType;
|
||||
}
|
||||
|
||||
cursor = PyObject_CallOneArg(factory, (PyObject *)self);
|
||||
if (cursor == NULL)
|
||||
return NULL;
|
||||
if (!PyObject_TypeCheck(cursor, state->CursorType)) {
|
||||
if (!PyObject_TypeCheck(cursor, self->state->CursorType)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"factory must return a cursor, not %.100s",
|
||||
Py_TYPE(cursor)->tp_name);
|
||||
|
@ -383,15 +384,15 @@ pysqlite_connection_close_impl(pysqlite_Connection *self)
|
|||
*/
|
||||
int pysqlite_check_connection(pysqlite_Connection* con)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (!con->initialized) {
|
||||
pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(con));
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
"Base Connection.__init__ not called.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!con->db) {
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
PyErr_SetString(con->state->ProgrammingError,
|
||||
"Cannot operate on a closed database.");
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -422,20 +423,20 @@ pysqlite_connection_commit_impl(pysqlite_Connection *self)
|
|||
rc = sqlite3_prepare_v2(self->db, "COMMIT", 7, &statement, NULL);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = pysqlite_step(statement);
|
||||
if (rc != SQLITE_DONE) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
rc = sqlite3_finalize(statement);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (rc != SQLITE_OK && !PyErr_Occurred()) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -472,20 +473,20 @@ pysqlite_connection_rollback_impl(pysqlite_Connection *self)
|
|||
rc = sqlite3_prepare_v2(self->db, "ROLLBACK", 9, &statement, NULL);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = pysqlite_step(statement);
|
||||
if (rc != SQLITE_DONE) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
rc = sqlite3_finalize(statement);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (rc != SQLITE_OK && !PyErr_Occurred()) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1672,7 +1673,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
|
|||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (bck_handle == NULL) {
|
||||
_pysqlite_seterror(bck_conn);
|
||||
_pysqlite_seterror(self->state, bck_conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1710,7 +1711,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
|
|||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(bck_conn);
|
||||
_pysqlite_seterror(self->state, bck_conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1762,7 +1763,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
|
|||
if (callable != Py_None) {
|
||||
Py_DECREF(callable);
|
||||
}
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct
|
|||
{
|
||||
PyObject_HEAD
|
||||
sqlite3* db;
|
||||
pysqlite_state *state;
|
||||
|
||||
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
|
||||
* bitwise combination thereof makes sense */
|
||||
|
|
|
@ -130,7 +130,8 @@ cursor_dealloc(pysqlite_Cursor *self)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
_pysqlite_get_converter(const char *keystr, Py_ssize_t keylen)
|
||||
_pysqlite_get_converter(pysqlite_state *state, const char *keystr,
|
||||
Py_ssize_t keylen)
|
||||
{
|
||||
PyObject *key;
|
||||
PyObject *upcase_key;
|
||||
|
@ -147,7 +148,6 @@ _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
retval = PyDict_GetItemWithError(state->converters, upcase_key);
|
||||
Py_DECREF(upcase_key);
|
||||
|
||||
|
@ -187,7 +187,9 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self)
|
|||
type_start = pos + 1;
|
||||
}
|
||||
else if (*pos == ']' && type_start != NULL) {
|
||||
converter = _pysqlite_get_converter(type_start, pos - type_start);
|
||||
pysqlite_state *state = self->connection->state;
|
||||
converter = _pysqlite_get_converter(state, type_start,
|
||||
pos - type_start);
|
||||
if (!converter && PyErr_Occurred()) {
|
||||
Py_CLEAR(self->row_cast_map);
|
||||
return -1;
|
||||
|
@ -206,7 +208,9 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self)
|
|||
* 'NUMBER(10)' to be treated as 'NUMBER', for example.
|
||||
* In other words, it will work as people expect it to work.*/
|
||||
if (*pos == ' ' || *pos == '(' || *pos == 0) {
|
||||
converter = _pysqlite_get_converter(decltype, pos - decltype);
|
||||
pysqlite_state *state = self->connection->state;
|
||||
converter = _pysqlite_get_converter(state, decltype,
|
||||
pos - decltype);
|
||||
if (!converter && PyErr_Occurred()) {
|
||||
Py_CLEAR(self->row_cast_map);
|
||||
return -1;
|
||||
|
@ -404,22 +408,21 @@ error:
|
|||
*/
|
||||
static int check_cursor(pysqlite_Cursor* cur)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
|
||||
if (!cur->initialized) {
|
||||
pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(cur));
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
"Base Cursor.__init__ not called.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cur->closed) {
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
PyErr_SetString(cur->connection->state->ProgrammingError,
|
||||
"Cannot operate on a closed cursor.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cur->locked) {
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
PyErr_SetString(cur->connection->state->ProgrammingError,
|
||||
"Recursive use of cursors not allowed.");
|
||||
return 0;
|
||||
}
|
||||
|
@ -439,7 +442,7 @@ begin_transaction(pysqlite_Connection *self)
|
|||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -449,7 +452,7 @@ begin_transaction(pysqlite_Connection *self)
|
|||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (rc != SQLITE_OK && !PyErr_Occurred()) {
|
||||
_pysqlite_seterror(self->db);
|
||||
_pysqlite_seterror(self->state, self->db);
|
||||
}
|
||||
|
||||
error:
|
||||
|
@ -470,7 +473,6 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation)
|
|||
static PyObject *
|
||||
_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
PyObject* parameters_list = NULL;
|
||||
PyObject* parameters_iter = NULL;
|
||||
PyObject* parameters = NULL;
|
||||
|
@ -568,6 +570,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
|
|||
}
|
||||
}
|
||||
|
||||
pysqlite_state *state = self->connection->state;
|
||||
while (1) {
|
||||
parameters = PyIter_Next(parameters_iter);
|
||||
if (!parameters) {
|
||||
|
@ -576,7 +579,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
|
|||
|
||||
pysqlite_statement_mark_dirty(self->statement);
|
||||
|
||||
pysqlite_statement_bind_parameters(self->statement, parameters);
|
||||
pysqlite_statement_bind_parameters(state, self->statement, parameters);
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -592,12 +595,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
|
|||
}
|
||||
}
|
||||
(void)pysqlite_statement_reset(self->statement);
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(state, self->connection->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pysqlite_build_row_cast_map(self) != 0) {
|
||||
_PyErr_FormatFromCause(self->connection->OperationalError,
|
||||
_PyErr_FormatFromCause(state->OperationalError,
|
||||
"Error while building row_cast_map");
|
||||
goto error;
|
||||
}
|
||||
|
@ -651,7 +654,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
|
|||
|
||||
if (rc == SQLITE_ROW) {
|
||||
if (multiple) {
|
||||
PyErr_SetString(self->connection->ProgrammingError,
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
"executemany() can only execute DML "
|
||||
"statements.");
|
||||
goto error;
|
||||
|
@ -773,6 +776,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||
}
|
||||
Py_DECREF(result);
|
||||
|
||||
pysqlite_state *state = self->connection->state;
|
||||
while (1) {
|
||||
const char *tail;
|
||||
|
||||
|
@ -784,7 +788,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||
&tail);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(state, self->connection->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -799,13 +803,13 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||
|
||||
if (rc != SQLITE_DONE) {
|
||||
(void)sqlite3_finalize(statement);
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(state, self->connection->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(statement);
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(state, self->connection->db);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -874,7 +878,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
|
|||
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
|
||||
(void)pysqlite_statement_reset(self->statement);
|
||||
Py_DECREF(next_row);
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(self->connection->state, self->connection->db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1023,15 +1027,17 @@ pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size,
|
|||
/*[clinic input]
|
||||
_sqlite3.Cursor.close as pysqlite_cursor_close
|
||||
|
||||
cls: defining_class
|
||||
|
||||
Closes the cursor.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
pysqlite_cursor_close_impl(pysqlite_Cursor *self)
|
||||
/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/
|
||||
pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls)
|
||||
/*[clinic end generated code: output=a08ab3d772f45438 input=28ba9b532ab46ba0]*/
|
||||
{
|
||||
if (!self->connection) {
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
pysqlite_state *state = pysqlite_get_state_by_cls(cls);
|
||||
PyErr_SetString(state->ProgrammingError,
|
||||
"Base Cursor.__init__ not called.");
|
||||
return NULL;
|
||||
|
|
|
@ -71,7 +71,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
|
|||
/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */
|
||||
|
||||
PyObject *
|
||||
pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||
pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj,
|
||||
PyObject *proto, PyObject *alt)
|
||||
{
|
||||
_Py_IDENTIFIER(__adapt__);
|
||||
_Py_IDENTIFIER(__conform__);
|
||||
|
@ -86,7 +87,6 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
|||
if (!key) {
|
||||
return NULL;
|
||||
}
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
adapter = PyDict_GetItemWithError(state->psyco_adapters, key);
|
||||
Py_DECREF(key);
|
||||
if (adapter) {
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
extern int pysqlite_microprotocols_init(PyObject *module);
|
||||
extern int pysqlite_microprotocols_add(
|
||||
PyTypeObject *type, PyObject *proto, PyObject *cast);
|
||||
extern PyObject *pysqlite_microprotocols_adapt(
|
||||
PyObject *obj, PyObject *proto, PyObject *alt);
|
||||
extern PyObject *pysqlite_microprotocols_adapt(pysqlite_state *state,
|
||||
PyObject *obj, PyObject *proto,
|
||||
PyObject *alt);
|
||||
|
||||
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */
|
||||
|
|
|
@ -158,7 +158,7 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type,
|
|||
state->BaseTypeAdapted = 1;
|
||||
}
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
pysqlite_state *state = pysqlite_get_state(module);
|
||||
PyObject *protocol = (PyObject *)state->PrepareProtocolType;
|
||||
rc = pysqlite_microprotocols_add(type, protocol, caster);
|
||||
if (rc == -1) {
|
||||
|
@ -239,7 +239,8 @@ pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto,
|
|||
PyObject *alt)
|
||||
/*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/
|
||||
{
|
||||
return pysqlite_microprotocols_adapt(obj, proto, alt);
|
||||
pysqlite_state *state = pysqlite_get_state(module);
|
||||
return pysqlite_microprotocols_adapt(state, obj, proto, alt);
|
||||
}
|
||||
|
||||
static int converters_init(PyObject* module)
|
||||
|
|
|
@ -65,6 +65,19 @@ extern pysqlite_state pysqlite_global_state;
|
|||
static inline pysqlite_state *
|
||||
pysqlite_get_state(PyObject *Py_UNUSED(module))
|
||||
{
|
||||
return &pysqlite_global_state; // Replace with PyModule_GetState
|
||||
}
|
||||
|
||||
static inline pysqlite_state *
|
||||
pysqlite_get_state_by_cls(PyTypeObject *Py_UNUSED(cls))
|
||||
{
|
||||
return &pysqlite_global_state; // Replace with PyType_GetModuleState
|
||||
}
|
||||
|
||||
static inline pysqlite_state *
|
||||
pysqlite_get_state_by_type(PyTypeObject *Py_UNUSED(tp))
|
||||
{
|
||||
// Replace with _PyType_GetModuleByDef & PyModule_GetState
|
||||
return &pysqlite_global_state;
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
|
|||
if (opid != Py_EQ && opid != Py_NE)
|
||||
Py_RETURN_NOTIMPLEMENTED;
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
pysqlite_state *state = pysqlite_get_state_by_cls(Py_TYPE(self));
|
||||
if (PyObject_TypeCheck(_other, state->RowType)) {
|
||||
pysqlite_Row *other = (pysqlite_Row *)_other;
|
||||
int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef enum {
|
|||
pysqlite_Statement *
|
||||
pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
pysqlite_state *state = connection->state;
|
||||
assert(PyUnicode_Check(sql));
|
||||
Py_ssize_t size;
|
||||
const char *sql_cstr = PyUnicode_AsUTF8AndSize(sql, &size);
|
||||
|
@ -83,7 +83,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
|||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(db);
|
||||
_pysqlite_seterror(state, db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -209,9 +209,9 @@ final:
|
|||
}
|
||||
|
||||
/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */
|
||||
static int _need_adapt(PyObject* obj)
|
||||
static int
|
||||
_need_adapt(pysqlite_state *state, PyObject *obj)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->BaseTypeAdapted) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -224,9 +224,11 @@ static int _need_adapt(PyObject* obj)
|
|||
}
|
||||
}
|
||||
|
||||
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters)
|
||||
void
|
||||
pysqlite_statement_bind_parameters(pysqlite_state *state,
|
||||
pysqlite_Statement *self,
|
||||
PyObject *parameters)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
PyObject* current_param;
|
||||
PyObject* adapted;
|
||||
const char* binding_name;
|
||||
|
@ -272,11 +274,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_need_adapt(current_param)) {
|
||||
if (!_need_adapt(state, current_param)) {
|
||||
adapted = current_param;
|
||||
} else {
|
||||
PyObject *protocol = (PyObject *)state->PrepareProtocolType;
|
||||
adapted = pysqlite_microprotocols_adapt(current_param,
|
||||
adapted = pysqlite_microprotocols_adapt(state, current_param,
|
||||
protocol,
|
||||
current_param);
|
||||
Py_DECREF(current_param);
|
||||
|
@ -332,11 +334,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_need_adapt(current_param)) {
|
||||
if (!_need_adapt(state, current_param)) {
|
||||
adapted = current_param;
|
||||
} else {
|
||||
PyObject *protocol = (PyObject *)state->PrepareProtocolType;
|
||||
adapted = pysqlite_microprotocols_adapt(current_param,
|
||||
adapted = pysqlite_microprotocols_adapt(state, current_param,
|
||||
protocol,
|
||||
current_param);
|
||||
Py_DECREF(current_param);
|
||||
|
|
|
@ -41,7 +41,9 @@ typedef struct
|
|||
pysqlite_Statement *pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql);
|
||||
|
||||
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter);
|
||||
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters);
|
||||
void pysqlite_statement_bind_parameters(pysqlite_state *state,
|
||||
pysqlite_Statement *self,
|
||||
PyObject *parameters);
|
||||
|
||||
int pysqlite_statement_finalize(pysqlite_Statement* self);
|
||||
int pysqlite_statement_reset(pysqlite_Statement* self);
|
||||
|
|
|
@ -41,9 +41,8 @@ pysqlite_step(sqlite3_stmt *statement)
|
|||
* Returns the error code (0 means no error occurred).
|
||||
*/
|
||||
int
|
||||
_pysqlite_seterror(sqlite3 *db)
|
||||
_pysqlite_seterror(pysqlite_state *state, sqlite3 *db)
|
||||
{
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
int errorcode = sqlite3_errcode(db);
|
||||
|
||||
switch (errorcode)
|
||||
|
|
|
@ -35,7 +35,7 @@ int pysqlite_step(sqlite3_stmt *statement);
|
|||
* Checks the SQLite error code and sets the appropriate DB-API exception.
|
||||
* Returns the error code (0 means no error occurred).
|
||||
*/
|
||||
int _pysqlite_seterror(sqlite3 *db);
|
||||
int _pysqlite_seterror(pysqlite_state *state, sqlite3 *db);
|
||||
|
||||
sqlite_int64 _pysqlite_long_as_int64(PyObject * value);
|
||||
|
||||
|
|
Loading…
Reference in New Issue