From a5906b34cc8f49c7da8373c718ef3d02f0f7d49e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 13 Jun 2020 22:16:22 +0200 Subject: [PATCH 1/9] Convert module level functions except connect Note: Moves sqlite3.adapt from microprotocols.c to module.c --- Modules/_sqlite/clinic/module.c.h | 216 ++++++++++++++++++++++++++++++ Modules/_sqlite/microprotocols.c | 13 -- Modules/_sqlite/microprotocols.h | 5 - Modules/_sqlite/module.c | 163 ++++++++++++---------- 4 files changed, 309 insertions(+), 88 deletions(-) create mode 100644 Modules/_sqlite/clinic/module.c.h diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h new file mode 100644 index 00000000000000..af9d39edb5168f --- /dev/null +++ b/Modules/_sqlite/clinic/module.c.h @@ -0,0 +1,216 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pysqlite_complete_statement__doc__, +"complete_statement($module, statement, /)\n" +"--\n" +"\n" +"Checks if a string contains a complete SQL statement. Non-standard."); + +#define PYSQLITE_COMPLETE_STATEMENT_METHODDEF \ + {"complete_statement", (PyCFunction)pysqlite_complete_statement, METH_O, pysqlite_complete_statement__doc__}, + +static PyObject * +pysqlite_complete_statement_impl(PyObject *module, const char *statement); + +static PyObject * +pysqlite_complete_statement(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *statement; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("complete_statement", "argument", "str", arg); + goto exit; + } + Py_ssize_t statement_length; + statement = PyUnicode_AsUTF8AndSize(arg, &statement_length); + if (statement == NULL) { + goto exit; + } + if (strlen(statement) != (size_t)statement_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = pysqlite_complete_statement_impl(module, statement); + +exit: + return return_value; +} + +#if defined(HAVE_SHARED_CACHE) + +PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, +"enable_shared_cache($module, enable, /)\n" +"--\n" +"\n" +"Enable or disable shared cache mode for the calling thread.\n" +"\n" +"Experimental/Non-standard."); + +#define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF \ + {"enable_shared_cache", (PyCFunction)pysqlite_enable_shared_cache, METH_O, pysqlite_enable_shared_cache__doc__}, + +static PyObject * +pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable); + +static PyObject * +pysqlite_enable_shared_cache(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int do_enable; + + do_enable = _PyLong_AsInt(arg); + if (do_enable == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_enable_shared_cache_impl(module, do_enable); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SHARED_CACHE) */ + +PyDoc_STRVAR(pysqlite_register_adapter__doc__, +"register_adapter($module, type, caster, /)\n" +"--\n" +"\n" +"Registers an adapter with pysqlite\'s adapter registry. Non-standard."); + +#define PYSQLITE_REGISTER_ADAPTER_METHODDEF \ + {"register_adapter", (PyCFunction)(void(*)(void))pysqlite_register_adapter, METH_FASTCALL, pysqlite_register_adapter__doc__}, + +static PyObject * +pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, + PyObject *caster); + +static PyObject * +pysqlite_register_adapter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + PyObject *caster; + + if (!_PyArg_CheckPositional("register_adapter", nargs, 2, 2)) { + goto exit; + } + type = (PyTypeObject *)args[0]; + caster = args[1]; + return_value = pysqlite_register_adapter_impl(module, type, caster); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_register_converter__doc__, +"register_converter($module, name, converter, /)\n" +"--\n" +"\n" +"Registers a converter with pysqlite. Non-standard."); + +#define PYSQLITE_REGISTER_CONVERTER_METHODDEF \ + {"register_converter", (PyCFunction)(void(*)(void))pysqlite_register_converter, METH_FASTCALL, pysqlite_register_converter__doc__}, + +static PyObject * +pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, + PyObject *callable); + +static PyObject * +pysqlite_register_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *orig_name; + PyObject *callable; + + if (!_PyArg_CheckPositional("register_converter", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("register_converter", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + orig_name = args[0]; + callable = args[1]; + return_value = pysqlite_register_converter_impl(module, orig_name, callable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_enable_callback_trace__doc__, +"enable_callback_tracebacks($module, enable, /)\n" +"--\n" +"\n" +"Enable or disable callback functions throwing errors to stderr."); + +#define PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF \ + {"enable_callback_tracebacks", (PyCFunction)pysqlite_enable_callback_trace, METH_O, pysqlite_enable_callback_trace__doc__}, + +static PyObject * +pysqlite_enable_callback_trace_impl(PyObject *module, int enable); + +static PyObject * +pysqlite_enable_callback_trace(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int enable; + + enable = _PyLong_AsInt(arg); + if (enable == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_enable_callback_trace_impl(module, enable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_adapt__doc__, +"adapt($module, obj, proto=PrepareProtocolType, alt=, /)\n" +"--\n" +"\n" +"Adapt given object to given protocol. Non-standard."); + +#define PYSQLITE_ADAPT_METHODDEF \ + {"adapt", (PyCFunction)(void(*)(void))pysqlite_adapt, METH_FASTCALL, pysqlite_adapt__doc__}, + +static PyObject * +pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, + PyObject *alt); + +static PyObject * +pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; + PyObject *alt = NULL; + + if (!_PyArg_CheckPositional("adapt", nargs, 1, 3)) { + goto exit; + } + obj = args[0]; + if (nargs < 2) { + goto skip_optional; + } + proto = args[1]; + if (nargs < 3) { + goto skip_optional; + } + alt = args[2]; +skip_optional: + return_value = pysqlite_adapt_impl(module, obj, proto, alt); + +exit: + return return_value; +} + +#ifndef PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF + #define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF +#endif /* !defined(PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF) */ +/*[clinic end generated code: output=2f740fe39ac0ec71 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 3b2d7f42b87353..0ef1ff95a4971e 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -29,7 +29,6 @@ #include "microprotocols.h" #include "prepare_protocol.h" - /** the adapters registry **/ static PyObject *psyco_adapters = NULL; @@ -145,15 +144,3 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) PyErr_SetString(pysqlite_ProgrammingError, "can't adapt"); return NULL; } - -/** module-level functions **/ - -PyObject * -pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) -{ - PyObject *obj, *alt = NULL; - PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; - - if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; - return pysqlite_microprotocols_adapt(obj, proto, alt); -} diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index 5418c2b98fd751..bdd863b1733aa1 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -44,9 +44,4 @@ extern int pysqlite_microprotocols_add( extern PyObject *pysqlite_microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); -extern PyObject * - pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); -#define pysqlite_adapt_doc \ - "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." - #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82f58eb2480261..b7a3ac2eeea450 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -33,6 +33,12 @@ #error "SQLite 3.7.3 or higher required" #endif +#include "clinic/module.c.h" +/*[clinic input] +module _sqlite3 +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ + /* static objects at module-level */ PyObject *pysqlite_Error = NULL; @@ -102,18 +108,20 @@ Opens a connection to the SQLite database file *database*. You can use\n\ \":memory:\" to open a database connection to a database that resides in\n\ RAM instead of on disk."); -static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* - kwargs) -{ - static char *kwlist[] = {"statement", NULL}; - char* statement; +/*[clinic input] +_sqlite3.complete_statement as pysqlite_complete_statement - PyObject* result; + statement: str + / - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) - { - return NULL; - } +Checks if a string contains a complete SQL statement. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_complete_statement_impl(PyObject *module, const char *statement) +/*[clinic end generated code: output=e55f1ff1952df558 input=b15b778a9c1b557b]*/ +{ + PyObject* result; if (sqlite3_complete(statement)) { result = Py_True; @@ -126,23 +134,23 @@ static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* return result; } -PyDoc_STRVAR(module_complete_doc, -"complete_statement(sql)\n\ -\n\ -Checks if a string contains a complete SQL statement. Non-standard."); +/*[clinic input] +_sqlite3.enable_shared_cache as pysqlite_enable_shared_cache -static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* - kwargs) + enable as do_enable: int + / + +Enable or disable shared cache mode for the calling thread. + +Experimental/Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable) +/*[clinic end generated code: output=259c74eedee1516b input=6c608c515bd7caba]*/ { - static char *kwlist[] = {"do_enable", NULL}; - int do_enable; int rc; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) - { - return NULL; - } - rc = sqlite3_enable_shared_cache(do_enable); if (rc != SQLITE_OK) { @@ -153,22 +161,23 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb } } -PyDoc_STRVAR(module_enable_shared_cache_doc, -"enable_shared_cache(do_enable)\n\ -\n\ -Enable or disable shared cache mode for the calling thread.\n\ -Experimental/Non-standard."); +/*[clinic input] +_sqlite3.register_adapter as pysqlite_register_adapter + + type: object(type='PyTypeObject *') + caster: object + / -static PyObject* module_register_adapter(PyObject* self, PyObject* args) +Registers an adapter with pysqlite's adapter registry. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, + PyObject *caster) +/*[clinic end generated code: output=a287e8db18e8af23 input=839dad90e2492725]*/ { - PyTypeObject* type; - PyObject* caster; int rc; - if (!PyArg_ParseTuple(args, "OO", &type, &caster)) { - return NULL; - } - /* a basic type is adapted; there's a performance optimization if that's not the case * (99 % of all usages) */ if (type == &PyLong_Type || type == &PyFloat_Type @@ -183,23 +192,25 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) Py_RETURN_NONE; } -PyDoc_STRVAR(module_register_adapter_doc, -"register_adapter(type, callable)\n\ -\n\ -Registers an adapter with pysqlite's adapter registry. Non-standard."); +/*[clinic input] +_sqlite3.register_converter as pysqlite_register_converter + + name as orig_name: unicode + converter as callable: object + / -static PyObject* module_register_converter(PyObject* self, PyObject* args) +Registers a converter with pysqlite. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, + PyObject *callable) +/*[clinic end generated code: output=a2f2bfeed7230062 input=e074cf7f4890544f]*/ { - PyObject* orig_name; PyObject* name = NULL; - PyObject* callable; PyObject* retval = NULL; _Py_IDENTIFIER(upper); - if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { - return NULL; - } - /* convert the name to upper case */ name = _PyObject_CallMethodIdNoArgs(orig_name, &PyId_upper); if (!name) { @@ -217,24 +228,42 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) return retval; } -PyDoc_STRVAR(module_register_converter_doc, -"register_converter(typename, callable)\n\ -\n\ -Registers a converter with pysqlite. Non-standard."); +/*[clinic input] +_sqlite3.enable_callback_tracebacks as pysqlite_enable_callback_trace -static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) + enable: int + / + +Enable or disable callback functions throwing errors to stderr. +[clinic start generated code]*/ + +static PyObject * +pysqlite_enable_callback_trace_impl(PyObject *module, int enable) +/*[clinic end generated code: output=4ff1d051c698f194 input=cb79d3581eb77c40]*/ { - if (!PyArg_ParseTuple(args, "i", &_pysqlite_enable_callback_tracebacks)) { - return NULL; - } + _pysqlite_enable_callback_tracebacks = enable; Py_RETURN_NONE; } -PyDoc_STRVAR(enable_callback_tracebacks_doc, -"enable_callback_tracebacks(flag)\n\ -\n\ -Enable or disable callback functions throwing errors to stderr."); +/*[clinic input] +_sqlite3.adapt as pysqlite_adapt + + obj: object + proto: object(c_default='(PyObject*)&pysqlite_PrepareProtocolType') = PrepareProtocolType + alt: object = NULL + / + +Adapt given object to given protocol. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, + PyObject *alt) +/*[clinic end generated code: output=0c3927c5fcd23dd9 input=37bc55a5a6ee407c]*/ +{ + return pysqlite_microprotocols_adapt(obj, proto, alt); +} static void converters_init(PyObject* dict) { @@ -249,18 +278,12 @@ static void converters_init(PyObject* dict) static PyMethodDef module_methods[] = { {"connect", (PyCFunction)(void(*)(void))module_connect, METH_VARARGS | METH_KEYWORDS, module_connect_doc}, - {"complete_statement", (PyCFunction)(void(*)(void))module_complete, - METH_VARARGS | METH_KEYWORDS, module_complete_doc}, - {"enable_shared_cache", (PyCFunction)(void(*)(void))module_enable_shared_cache, - METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, - {"register_adapter", (PyCFunction)module_register_adapter, - METH_VARARGS, module_register_adapter_doc}, - {"register_converter", (PyCFunction)module_register_converter, - METH_VARARGS, module_register_converter_doc}, - {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS, - pysqlite_adapt_doc}, - {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, - METH_VARARGS, enable_callback_tracebacks_doc}, + PYSQLITE_ADAPT_METHODDEF + PYSQLITE_COMPLETE_STATEMENT_METHODDEF + PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF + PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF + PYSQLITE_REGISTER_ADAPTER_METHODDEF + PYSQLITE_REGISTER_CONVERTER_METHODDEF {NULL, NULL} }; From 2557de53ff46fec4f2011f88ef04b4f0c81e037c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 13 Jun 2020 23:38:44 +0200 Subject: [PATCH 2/9] Convert Connection --- Modules/_sqlite/clinic/connection.c.h | 685 ++++++++++++++++++++++++++ Modules/_sqlite/connection.c | 495 +++++++++++-------- Modules/_sqlite/connection.h | 4 - Modules/_sqlite/cursor.c | 3 +- 4 files changed, 977 insertions(+), 210 deletions(-) create mode 100644 Modules/_sqlite/clinic/connection.c.h diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h new file mode 100644 index 00000000000000..ddae4a5b108817 --- /dev/null +++ b/Modules/_sqlite/clinic/connection.c.h @@ -0,0 +1,685 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pysqlite_connection_cursor__doc__, +"cursor($self, /, factory=)\n" +"--\n" +"\n" +"Return a cursor for the connection."); + +#define PYSQLITE_CONNECTION_CURSOR_METHODDEF \ + {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, + +static PyObject * +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory); + +static PyObject * +pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"factory", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *factory = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + factory = args[0]; +skip_optional_pos: + return_value = pysqlite_connection_cursor_impl(self, factory); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Closes the connection."); + +#define PYSQLITE_CONNECTION_CLOSE_METHODDEF \ + {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, pysqlite_connection_close__doc__}, + +static PyObject * +pysqlite_connection_close_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_close(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_close_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_commit__doc__, +"commit($self, /)\n" +"--\n" +"\n" +"Commit the current transaction."); + +#define PYSQLITE_CONNECTION_COMMIT_METHODDEF \ + {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, pysqlite_connection_commit__doc__}, + +static PyObject * +pysqlite_connection_commit_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_commit(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_commit_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_rollback__doc__, +"rollback($self, /)\n" +"--\n" +"\n" +"Roll back the current transaction."); + +#define PYSQLITE_CONNECTION_ROLLBACK_METHODDEF \ + {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, pysqlite_connection_rollback__doc__}, + +static PyObject * +pysqlite_connection_rollback_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_rollback(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_rollback_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_create_function__doc__, +"create_function($self, /, name, narg, func, *, deterministic=False)\n" +"--\n" +"\n" +"Creates a new function. Non-standard."); + +#define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ + {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, + +static PyObject * +pysqlite_connection_create_function_impl(pysqlite_Connection *self, + const char *name, int narg, + PyObject *func, int deterministic); + +static PyObject * +pysqlite_connection_create_function(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "create_function", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + const char *name; + int narg; + PyObject *func; + int deterministic = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_function", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + narg = _PyLong_AsInt(args[1]); + if (narg == -1 && PyErr_Occurred()) { + goto exit; + } + func = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + deterministic = PyObject_IsTrue(args[3]); + if (deterministic < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = pysqlite_connection_create_function_impl(self, name, narg, func, deterministic); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, +"create_aggregate($self, /, name, n_arg, aggregate_class)\n" +"--\n" +"\n" +"Creates a new aggregate. Non-standard."); + +#define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ + {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, + +static PyObject * +pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, + const char *name, int n_arg, + PyObject *aggregate_class); + +static PyObject * +pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "create_aggregate", 0}; + PyObject *argsbuf[3]; + const char *name; + int n_arg; + PyObject *aggregate_class; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_aggregate", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + n_arg = _PyLong_AsInt(args[1]); + if (n_arg == -1 && PyErr_Occurred()) { + goto exit; + } + aggregate_class = args[2]; + return_value = pysqlite_connection_create_aggregate_impl(self, name, n_arg, aggregate_class); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, +"set_authorizer($self, authorizer_callback, /)\n" +"--\n" +"\n" +"Sets authorizer callback. Non-standard."); + +#define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ + {"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_O, pysqlite_connection_set_authorizer__doc__}, + +PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, +"set_progress_handler($self, /, progress_handler, n)\n" +"--\n" +"\n" +"Sets progress handler callback. Non-standard."); + +#define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ + {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, + +static PyObject * +pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, + PyObject *progress_handler, + int n); + +static PyObject * +pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"progress_handler", "n", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_progress_handler", 0}; + PyObject *argsbuf[2]; + PyObject *progress_handler; + int n; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + progress_handler = args[0]; + n = _PyLong_AsInt(args[1]); + if (n == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_connection_set_progress_handler_impl(self, progress_handler, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, +"set_trace_callback($self, trace_callback, /)\n" +"--\n" +"\n" +"Sets a trace callback called for each SQL statement (passed as unicode).\n" +"\n" +"Non-standard."); + +#define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ + {"set_trace_callback", (PyCFunction)pysqlite_connection_set_trace_callback, METH_O, pysqlite_connection_set_trace_callback__doc__}, + +#if defined(HAVE_LOAD_EXTENSION) + +PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, +"enable_load_extension($self, enable, /)\n" +"--\n" +"\n" +"Enable dynamic loading of SQLite extension modules. Non-standard."); + +#define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF \ + {"enable_load_extension", (PyCFunction)pysqlite_connection_enable_load_extension, METH_O, pysqlite_connection_enable_load_extension__doc__}, + +static PyObject * +pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, + int onoff); + +static PyObject * +pysqlite_connection_enable_load_extension(pysqlite_Connection *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int onoff; + + onoff = _PyLong_AsInt(arg); + if (onoff == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = pysqlite_connection_enable_load_extension_impl(self, onoff); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LOAD_EXTENSION) */ + +#if defined(HAVE_LOAD_EXTENSION) + +PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, +"load_extension($self, name, /)\n" +"--\n" +"\n" +"Load SQLite extension module. Non-standard."); + +#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF \ + {"load_extension", (PyCFunction)pysqlite_connection_load_extension, METH_O, pysqlite_connection_load_extension__doc__}, + +static PyObject * +pysqlite_connection_load_extension_impl(pysqlite_Connection *self, + const char *extension_name); + +static PyObject * +pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *extension_name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("load_extension", "argument", "str", arg); + goto exit; + } + Py_ssize_t extension_name_length; + extension_name = PyUnicode_AsUTF8AndSize(arg, &extension_name_length); + if (extension_name == NULL) { + goto exit; + } + if (strlen(extension_name) != (size_t)extension_name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = pysqlite_connection_load_extension_impl(self, extension_name); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LOAD_EXTENSION) */ + +PyDoc_STRVAR(pysqlite_connection_execute__doc__, +"execute($self, sql, /, parameters=)\n" +"--\n" +"\n" +"Executes a SQL statement. Non-standard."); + +#define PYSQLITE_CONNECTION_EXECUTE_METHODDEF \ + {"execute", (PyCFunction)(void(*)(void))pysqlite_connection_execute, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_execute__doc__}, + +static PyObject * +pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, + PyObject *parameters); + +static PyObject * +pysqlite_connection_execute(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "parameters", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "execute", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *sql; + PyObject *parameters = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("execute", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + parameters = args[1]; +skip_optional_pos: + return_value = pysqlite_connection_execute_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_executemany__doc__, +"executemany($self, sql, parameters, /)\n" +"--\n" +"\n" +"Repeatedly executes a SQL statement. Non-standard."); + +#define PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF \ + {"executemany", (PyCFunction)(void(*)(void))pysqlite_connection_executemany, METH_FASTCALL, pysqlite_connection_executemany__doc__}, + +static PyObject * +pysqlite_connection_executemany_impl(pysqlite_Connection *self, + PyObject *sql, PyObject *parameters); + +static PyObject * +pysqlite_connection_executemany(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *parameters; + + if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + parameters = args[1]; + return_value = pysqlite_connection_executemany_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_executescript__doc__, +"executescript($self, sql_script, /)\n" +"--\n" +"\n"); + +#define PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF \ + {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_O, pysqlite_connection_executescript__doc__}, + +PyDoc_STRVAR(pysqlite_connection_interrupt__doc__, +"interrupt($self, /)\n" +"--\n" +"\n" +"Abort any pending database operation. Non-standard."); + +#define PYSQLITE_CONNECTION_INTERRUPT_METHODDEF \ + {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, pysqlite_connection_interrupt__doc__}, + +static PyObject * +pysqlite_connection_interrupt_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_interrupt(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_interrupt_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_iterdump__doc__, +"iterdump($self, /)\n" +"--\n" +"\n" +"Returns iterator to the dump of the database in an SQL text format.\n" +"\n" +"Non-standard."); + +#define PYSQLITE_CONNECTION_ITERDUMP_METHODDEF \ + {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, pysqlite_connection_iterdump__doc__}, + +static PyObject * +pysqlite_connection_iterdump_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_iterdump_impl(self); +} + +#if defined(HAVE_BACKUP_API) + +PyDoc_STRVAR(pysqlite_connection_backup__doc__, +"backup($self, /, target=, *, pages=-1, progress=None,\n" +" name=\'main\', sleep=0.25)\n" +"--\n" +"\n"); + +#define PYSQLITE_CONNECTION_BACKUP_METHODDEF \ + {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, + +static PyObject * +pysqlite_connection_backup_impl(pysqlite_Connection *self, + pysqlite_Connection *target, int pages, + PyObject *progress, const char *name, + double sleep); + +static PyObject * +pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + pysqlite_Connection *target = NULL; + int pages = -1; + PyObject *progress = Py_None; + const char *name = "main"; + double sleep = 0.25; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyObject_TypeCheck(args[0], &pysqlite_ConnectionType)) { + _PyArg_BadArgument("backup", "argument 'target'", (&pysqlite_ConnectionType)->tp_name, args[0]); + goto exit; + } + target = (pysqlite_Connection *)args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + pages = _PyLong_AsInt(args[1]); + if (pages == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + progress = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("backup", "argument 'name'", "str", args[3]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[3], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_CheckExact(args[4])) { + sleep = PyFloat_AS_DOUBLE(args[4]); + } + else + { + sleep = PyFloat_AsDouble(args[4]); + if (sleep == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional_kwonly: + return_value = pysqlite_connection_backup_impl(self, target, pages, progress, name, sleep); + +exit: + return return_value; +} + +#endif /* defined(HAVE_BACKUP_API) */ + +PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, +"create_collation($self, name, callback, /)\n" +"--\n" +"\n" +"Creates a collation function. Non-standard."); + +#define PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF \ + {"create_collation", (PyCFunction)(void(*)(void))pysqlite_connection_create_collation, METH_FASTCALL, pysqlite_connection_create_collation__doc__}, + +static PyObject * +pysqlite_connection_create_collation_impl(pysqlite_Connection *self, + PyObject *name, PyObject *callable); + +static PyObject * +pysqlite_connection_create_collation(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *callable; + + if (!_PyArg_CheckPositional("create_collation", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_collation", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + name = args[0]; + callable = args[1]; + return_value = pysqlite_connection_create_collation_impl(self, name, callable); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_connection_enter__doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Called when the connection is used as a context manager.\n" +"\n" +"Returns itself as a convenience to the caller."); + +#define PYSQLITE_CONNECTION_ENTER_METHODDEF \ + {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, pysqlite_connection_enter__doc__}, + +static PyObject * +pysqlite_connection_enter_impl(pysqlite_Connection *self); + +static PyObject * +pysqlite_connection_enter(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_connection_enter_impl(self); +} + +PyDoc_STRVAR(pysqlite_connection_exit__doc__, +"__exit__($self, type, value, traceback, /)\n" +"--\n" +"\n" +"Called when the connection is used as a context manager.\n" +"\n" +"If there was any exception, a rollback takes place; otherwise we commit."); + +#define PYSQLITE_CONNECTION_EXIT_METHODDEF \ + {"__exit__", (PyCFunction)(void(*)(void))pysqlite_connection_exit, METH_FASTCALL, pysqlite_connection_exit__doc__}, + +static PyObject * +pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_tb; + + if (!_PyArg_CheckPositional("__exit__", nargs, 3, 3)) { + goto exit; + } + exc_type = args[0]; + exc_value = args[1]; + exc_tb = args[2]; + return_value = pysqlite_connection_exit_impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#ifndef PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF + #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF +#endif /* !defined(PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF) */ + +#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF + #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF +#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ + +#ifndef PYSQLITE_CONNECTION_BACKUP_METHODDEF + #define PYSQLITE_CONNECTION_BACKUP_METHODDEF +#endif /* !defined(PYSQLITE_CONNECTION_BACKUP_METHODDEF) */ +/*[clinic end generated code: output=2f69688f7e0cf5b3 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index f765ba1df24669..30c8b5672a39fd 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -37,6 +37,13 @@ #define HAVE_TRACE_V2 #endif +#include "clinic/connection.c.h" +/*[clinic input] +module _sqlite3 +class _sqlite3.Connection "pysqlite_Connection *" "&pysqlite_ConnectionType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=20047e60dfd58f65]*/ + _Py_IDENTIFIER(cursor); static const char * const begin_statements[] = { @@ -265,17 +272,20 @@ int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObjec return 0; } -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +/*[clinic input] +_sqlite3.Connection.cursor as pysqlite_connection_cursor + + factory: object = NULL + +Return a cursor for the connection. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) +/*[clinic end generated code: output=562432a9e6af2aa1 input=4127345aa091b650]*/ { - static char *kwlist[] = {"factory", NULL}; - PyObject* factory = NULL; PyObject* cursor; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, - &factory)) { - return NULL; - } - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -305,7 +315,15 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, return cursor; } -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.close as pysqlite_connection_close + +Closes the connection. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_close_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ { int rc; @@ -385,7 +403,15 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) } } -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.commit as pysqlite_connection_commit + +Commit the current transaction. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_commit_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=3da45579e89407f2 input=39c12c04dda276a8]*/ { int rc; const char* tail; @@ -427,7 +453,15 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) } } -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.rollback as pysqlite_connection_rollback + +Roll back the current transaction. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_rollback_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=b66fa0d43e7ef305 input=12d4e8d068942830]*/ { int rc; const char* tail; @@ -776,27 +810,31 @@ static void _destructor(void* args) Py_DECREF((PyObject*)args); } -PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; +/*[clinic input] +_sqlite3.Connection.create_function as pysqlite_connection_create_function + + name: str + narg: int + func: object + * + deterministic: bool = False + +Creates a new function. Non-standard. +[clinic start generated code]*/ - PyObject* func; - char* name; - int narg; +static PyObject * +pysqlite_connection_create_function_impl(pysqlite_Connection *self, + const char *name, int narg, + PyObject *func, int deterministic) +/*[clinic end generated code: output=07d1877dd98c0308 input=f2edcf073e815beb]*/ +{ int rc; - int deterministic = 0; int flags = SQLITE_UTF8; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|$p", kwlist, - &name, &narg, &func, &deterministic)) - { - return NULL; - } - if (deterministic) { #if SQLITE_VERSION_NUMBER < 3008003 PyErr_SetString(pysqlite_NotSupportedError, @@ -830,23 +868,28 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec Py_RETURN_NONE; } -PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* aggregate_class; +/*[clinic input] +_sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate - int n_arg; - char* name; - static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL }; + name: str + n_arg: int + aggregate_class: object + +Creates a new aggregate. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, + const char *name, int n_arg, + PyObject *aggregate_class) +/*[clinic end generated code: output=fbb2f858cfa4d8db input=c2e13bbf234500a5]*/ +{ int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate", - kwlist, &name, &n_arg, &aggregate_class)) { - return NULL; - } Py_INCREF(aggregate_class); rc = sqlite3_create_function_v2(self->db, name, @@ -978,22 +1021,26 @@ static void _trace_callback(void* user_arg, const char* statement_string) #endif } -static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* authorizer_cb; +/*[clinic input] +_sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer + + authorizer_callback as authorizer_cb: object + / + +Sets authorizer callback. Non-standard. +[clinic start generated code]*/ - static char *kwlist[] = { "authorizer_callback", NULL }; +static PyObject * +pysqlite_connection_set_authorizer(pysqlite_Connection *self, + PyObject *authorizer_cb) +/*[clinic end generated code: output=4f2f5f3f84d99092 input=1c43aa0c0939fec4]*/ +{ int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer", - kwlist, &authorizer_cb)) { - return NULL; - } - rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); @@ -1006,19 +1053,22 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P Py_RETURN_NONE; } -static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* progress_handler; - int n; +/*[clinic input] +_sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_handler - static char *kwlist[] = { "progress_handler", "n", NULL }; + progress_handler: object + n: int - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } +Sets progress handler callback. Non-standard. +[clinic start generated code]*/ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler", - kwlist, &progress_handler, &n)) { +static PyObject * +pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, + PyObject *progress_handler, + int n) +/*[clinic end generated code: output=35a7c10364cb1b04 input=857696c25f964c64]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -1034,23 +1084,23 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s Py_RETURN_NONE; } -/* - * Ref. - * - https://sqlite.org/c3ref/c_trace.html - * - https://sqlite.org/c3ref/trace_v2.html - */ -static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* trace_callback; +/*[clinic input] +_sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback - static char *kwlist[] = { "trace_callback", NULL }; + trace_callback: object + / - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } +Sets a trace callback called for each SQL statement (passed as unicode). - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_trace_callback", - kwlist, &trace_callback)) { +Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_set_trace_callback(pysqlite_Connection *self, + PyObject *trace_callback) +/*[clinic end generated code: output=efd1bf439e81696c input=05a4a14360e0e034]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } @@ -1076,19 +1126,26 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel } #ifndef SQLITE_OMIT_LOAD_EXTENSION -static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_extension + + enable as onoff: int + / + +Enable dynamic loading of SQLite extension modules. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, + int onoff) +/*[clinic end generated code: output=9cac37190d388baf input=7df2986f1602d6bd]*/ { int rc; - int onoff; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTuple(args, "i", &onoff)) { - return NULL; - } - rc = sqlite3_enable_load_extension(self->db, onoff); if (rc != SQLITE_OK) { @@ -1099,20 +1156,27 @@ static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObj } } -static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.load_extension as pysqlite_connection_load_extension + + name as extension_name: str + / + +Load SQLite extension module. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_load_extension_impl(pysqlite_Connection *self, + const char *extension_name) +/*[clinic end generated code: output=47eb1d7312bc97a7 input=0b711574560db9fc]*/ { int rc; - char* extension_name; char* errmsg; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!PyArg_ParseTuple(args, "s", &extension_name)) { - return NULL; - } - rc = sqlite3_load_extension(self->db, extension_name, 0, &errmsg); if (rc != 0) { PyErr_SetString(pysqlite_OperationalError, errmsg); @@ -1275,89 +1339,107 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py return NULL; } -PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.execute as pysqlite_connection_execute + + sql: unicode + / + parameters: object = NULL + +Executes a SQL statement. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=5be05ae01ee17ee4 input=ec86c00fe1b371be]*/ { + _Py_IDENTIFIER(execute); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "execute"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_execute, sql, parameters, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } -PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.executemany as pysqlite_connection_executemany + + sql: unicode + parameters: object + / + +Repeatedly executes a SQL statement. Non-standard. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_executemany_impl(pysqlite_Connection *self, + PyObject *sql, PyObject *parameters) +/*[clinic end generated code: output=776cd2fd20bfe71f input=4feab80659ffc82b]*/ { + _Py_IDENTIFIER(executemany); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "executemany"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executemany, sql, + parameters, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } -PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Connection.executescript as pysqlite_connection_executescript + + sql_script as script_obj: object + / + +[clinic start generated code]*/ + +static PyObject * +pysqlite_connection_executescript(pysqlite_Connection *self, + PyObject *script_obj) +/*[clinic end generated code: output=4c4f9d77aa0ae37d input=d577986d8f6bcaf4]*/ { + _Py_IDENTIFIER(executescript); PyObject* cursor = 0; PyObject* result = 0; - PyObject* method = 0; cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } - method = PyObject_GetAttrString(cursor, "executescript"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); + result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executescript, + script_obj, NULL); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); - Py_XDECREF(method); return cursor; } @@ -1417,8 +1499,15 @@ pysqlite_collation_callback( return result; } +/*[clinic input] +_sqlite3.Connection.interrupt as pysqlite_connection_interrupt + +Abort any pending database operation. Non-standard. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_interrupt_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=f193204bc9e70b47 input=4bd0ad083cf93aa7]*/ { PyObject* retval = NULL; @@ -1439,8 +1528,17 @@ pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) * Class method of Connection to call the Python function _iterdump * of the sqlite3 module. */ +/*[clinic input] +_sqlite3.Connection.iterdump as pysqlite_connection_iterdump + +Returns iterator to the dump of the database in an SQL text format. + +Non-standard. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_iterdump_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=586997aaf9808768 input=53bc907cb5eedb85]*/ { _Py_IDENTIFIER(_iterdump); PyObject* retval = NULL; @@ -1478,47 +1576,36 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) return retval; } +/*[clinic input] +_sqlite3.Connection.backup as pysqlite_connection_backup + + target: object(type='pysqlite_Connection *', subclass_of='&pysqlite_ConnectionType') = NULL + * + pages: int = -1 + progress: object = None + name: str = "main" + sleep: double = 0.250 + +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds) +pysqlite_connection_backup_impl(pysqlite_Connection *self, + pysqlite_Connection *target, int pages, + PyObject *progress, const char *name, + double sleep) +/*[clinic end generated code: output=306a3e6a38c36334 input=bc8f97c01ea55042]*/ { - PyObject *target = NULL; - int pages = -1; - PyObject *progress = Py_None; - const char *name = "main"; int rc; int callback_error = 0; - PyObject *sleep_obj = NULL; - int sleep_ms = 250; + int sleep_ms = sleep * 1000.0; sqlite3 *bck_conn; sqlite3_backup *bck_handle; - static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, - &pysqlite_ConnectionType, &target, - &pages, &progress, &name, &sleep_obj)) { - return NULL; - } - - if (sleep_obj != NULL) { - _PyTime_t sleep_secs; - if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, - _PyTime_ROUND_TIMEOUT)) { - return NULL; - } - _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, - _PyTime_ROUND_TIMEOUT); - if (ms < INT_MIN || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "sleep is too large"); - return NULL; - } - sleep_ms = (int)ms; - } - if (!pysqlite_check_connection((pysqlite_Connection *)target)) { + if (!pysqlite_check_connection(target)) { return NULL; } - if ((pysqlite_Connection *)target == self) { + if (target == self) { PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance"); return NULL; } @@ -1526,7 +1613,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * #if SQLITE_VERSION_NUMBER < 3008008 /* Since 3.8.8 this is already done, per commit https://www.sqlite.org/src/info/169b5505498c0a7e */ - if (!sqlite3_get_autocommit(((pysqlite_Connection *)target)->db)) { + if (!sqlite3_get_autocommit(target->db)) { PyErr_SetString(pysqlite_OperationalError, "target is in transaction"); return NULL; } @@ -1541,7 +1628,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * pages = -1; } - bck_conn = ((pysqlite_Connection *)target)->db; + bck_conn = target->db; Py_BEGIN_ALLOW_THREADS bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name); @@ -1629,12 +1716,22 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * } } +/*[clinic input] +_sqlite3.Connection.create_collation as pysqlite_connection_create_collation + + name: unicode + callback as callable: object + / + +Creates a collation function. Non-standard. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_create_collation_impl(pysqlite_Connection *self, + PyObject *name, PyObject *callable) +/*[clinic end generated code: output=0f63b8995565ae22 input=5c3898813a776cf2]*/ { - PyObject* callable; PyObject* uppercase_name = 0; - PyObject* name; PyObject* retval; Py_ssize_t i, len; _Py_IDENTIFIER(upper); @@ -1647,11 +1744,6 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - if (!PyArg_ParseTuple(args, "UO:create_collation(name, callback)", - &name, &callable)) { - goto finally; - } - uppercase_name = _PyObject_CallMethodIdOneArg((PyObject *)&PyUnicode_Type, &PyId_upper, name); if (!uppercase_name) { @@ -1717,28 +1809,43 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) return retval; } -/* Called when the connection is used as a context manager. Returns itself as a - * convenience to the caller. */ +/*[clinic input] +_sqlite3.Connection.__enter__ as pysqlite_connection_enter + +Called when the connection is used as a context manager. + +Returns itself as a convenience to the caller. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_enter(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_enter_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=457b09726d3e9dcd input=127d7a4f17e86d8f]*/ { Py_INCREF(self); return (PyObject*)self; } -/** Called when the connection is used as a context manager. If there was any - * exception, a rollback takes place; otherwise we commit. */ +/*[clinic input] +_sqlite3.Connection.__exit__ as pysqlite_connection_exit + + type as exc_type: object + value as exc_value: object + traceback as exc_tb: object + / + +Called when the connection is used as a context manager. + +If there was any exception, a rollback takes place; otherwise we commit. +[clinic start generated code]*/ + static PyObject * -pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) +pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb) +/*[clinic end generated code: output=0705200e9321202a input=bd66f1532c9c54a7]*/ { - PyObject* exc_type, *exc_value, *exc_tb; const char* method_name; PyObject* result; - if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { - return NULL; - } - if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { method_name = "commit"; } else { @@ -1765,48 +1872,26 @@ static PyGetSetDef connection_getset[] = { }; static PyMethodDef connection_methods[] = { - {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Return a cursor for the connection.")}, - {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, - PyDoc_STR("Closes the connection.")}, - {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, - PyDoc_STR("Commit the current transaction.")}, - {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, - PyDoc_STR("Roll back the current transaction.")}, - {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new function. Non-standard.")}, - {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new aggregate. Non-standard.")}, - {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets authorizer callback. Non-standard.")}, - #ifndef SQLITE_OMIT_LOAD_EXTENSION - {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, - PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")}, - {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, - PyDoc_STR("Load SQLite extension module. Non-standard.")}, - #endif - {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets progress handler callback. Non-standard.")}, - {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode). Non-standard.")}, - {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement. Non-standard.")}, - {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")}, - {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, - {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, - PyDoc_STR("Creates a collation function. Non-standard.")}, - {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, - PyDoc_STR("Abort any pending database operation. Non-standard.")}, - {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, - PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, - {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Makes a backup of the database. Non-standard.")}, - {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, - PyDoc_STR("For context manager. Non-standard.")}, - {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, - PyDoc_STR("For context manager. Non-standard.")}, + PYSQLITE_CONNECTION_BACKUP_METHODDEF + PYSQLITE_CONNECTION_CLOSE_METHODDEF + PYSQLITE_CONNECTION_COMMIT_METHODDEF + PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF + PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF + PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF + PYSQLITE_CONNECTION_CURSOR_METHODDEF + PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF + PYSQLITE_CONNECTION_ENTER_METHODDEF + PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF + PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF + PYSQLITE_CONNECTION_EXECUTE_METHODDEF + PYSQLITE_CONNECTION_EXIT_METHODDEF + PYSQLITE_CONNECTION_INTERRUPT_METHODDEF + PYSQLITE_CONNECTION_ITERDUMP_METHODDEF + PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF + PYSQLITE_CONNECTION_ROLLBACK_METHODDEF + PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF + PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF + PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF {NULL, NULL} }; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 206085e00a00c7..8ea7d9cc3dee99 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -110,11 +110,7 @@ extern PyTypeObject pysqlite_ConnectionType; PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); void pysqlite_connection_dealloc(pysqlite_Connection* self); -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args); PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args); PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 5cfb4b97d61dfe..0376030edc154e 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -625,6 +625,7 @@ PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) static PyObject * pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) { + _Py_IDENTIFIER(commit); PyObject* script_obj; const char* script_cstr; sqlite3_stmt* statement; @@ -652,7 +653,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) } /* commit first */ - result = pysqlite_connection_commit(self->connection, NULL); + result = _PyObject_CallMethodIdNoArgs((PyObject *)self->connection, &PyId_commit); if (!result) { goto error; } From 6e1a726985319c212fee4ceb787510d8f29d095c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 13 Jun 2020 23:48:19 +0200 Subject: [PATCH 3/9] Convert Row --- Modules/_sqlite/clinic/row.c.h | 56 ++++++++++++++++++++++++++++++++++ Modules/_sqlite/row.c | 51 ++++++++++++++++++------------- 2 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 Modules/_sqlite/clinic/row.c.h diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h new file mode 100644 index 00000000000000..98e410219372e6 --- /dev/null +++ b/Modules/_sqlite/clinic/row.c.h @@ -0,0 +1,56 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, + PyObject *data); + +static PyObject * +pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + pysqlite_Cursor *cursor; + PyObject *data; + + if ((type == &pysqlite_RowType) && + !_PyArg_NoKeywords("Row", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Row", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), &pysqlite_CursorType)) { + _PyArg_BadArgument("Row", "argument 1", (&pysqlite_CursorType)->tp_name, PyTuple_GET_ITEM(args, 0)); + goto exit; + } + cursor = (pysqlite_Cursor *)PyTuple_GET_ITEM(args, 0); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 1))) { + _PyArg_BadArgument("Row", "argument 2", "tuple", PyTuple_GET_ITEM(args, 1)); + goto exit; + } + data = PyTuple_GET_ITEM(args, 1); + return_value = pysqlite_row_new_impl(type, cursor, data); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_row_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n" +"Returns the keys of the row."); + +#define PYSQLITE_ROW_KEYS_METHODDEF \ + {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, pysqlite_row_keys__doc__}, + +static PyObject * +pysqlite_row_keys_impl(pysqlite_Row *self); + +static PyObject * +pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_row_keys_impl(self); +} +/*[clinic end generated code: output=64c70362f4bfe669 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 4b47108278a0ab..825ccba7205291 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -23,6 +23,13 @@ #include "row.h" #include "cursor.h" +#include "clinic/row.c.h" + +/*[clinic input] +module _sqlite3 +class _sqlite3.Row "pysqlite_Row *" "&pysqlite_RowType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5fe72209a8a6e40c]*/ void pysqlite_row_dealloc(pysqlite_Row* self) { @@ -32,30 +39,25 @@ void pysqlite_row_dealloc(pysqlite_Row* self) Py_TYPE(self)->tp_free((PyObject*)self); } +/*[clinic input] +@classmethod +_sqlite3.Row.__new__ as pysqlite_row_new + + cursor: object(type='pysqlite_Cursor *', subclass_of='&pysqlite_CursorType') + data: object(subclass_of='&PyTuple_Type') + / + +[clinic start generated code]*/ + static PyObject * -pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, + PyObject *data) +/*[clinic end generated code: output=10d58b09a819a4c1 input=3bb62e4657f18d81]*/ { pysqlite_Row *self; - PyObject* data; - pysqlite_Cursor* cursor; assert(type != NULL && type->tp_alloc != NULL); - if (!_PyArg_NoKeywords("Row", kwargs)) - return NULL; - if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) - return NULL; - - if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { - PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); - return NULL; - } - - if (!PyTuple_Check(data)) { - PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); - return NULL; - } - self = (pysqlite_Row *) type->tp_alloc(type, 0); if (self == NULL) return NULL; @@ -156,7 +158,15 @@ pysqlite_row_length(pysqlite_Row* self) return PyTuple_GET_SIZE(self->data); } -PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored)) +/*[clinic input] +_sqlite3.Row.keys as pysqlite_row_keys + +Returns the keys of the row. +[clinic start generated code]*/ + +static PyObject * +pysqlite_row_keys_impl(pysqlite_Row *self) +/*[clinic end generated code: output=efe3dfb3af6edc07 input=7549a122827c5563]*/ { PyObject* list; Py_ssize_t nitems, i; @@ -221,8 +231,7 @@ static PySequenceMethods pysqlite_row_as_sequence = { static PyMethodDef pysqlite_row_methods[] = { - {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, - PyDoc_STR("Returns the keys of the row.")}, + PYSQLITE_ROW_KEYS_METHODDEF {NULL, NULL} }; From 311740ff18d780dc327c5a7264130fb07676e80c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 14 Jun 2020 00:07:04 +0200 Subject: [PATCH 4/9] Convert Cache --- Modules/_sqlite/cache.c | 55 +++++++++++++++++++++------- Modules/_sqlite/cache.h | 2 - Modules/_sqlite/clinic/cache.c.h | 63 ++++++++++++++++++++++++++++++++ Modules/_sqlite/cursor.c | 7 +++- 4 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 Modules/_sqlite/clinic/cache.c.h diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 758fc022f78108..4abfa270b2e72f 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -23,6 +23,13 @@ #include "cache.h" #include +#include "clinic/cache.c.h" + +/*[clinic input] +module _sqlite3 +class _sqlite3.Cache "pysqlite_Cache *" "&pysqlite_CacheType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94e9b64faa911d27]*/ /* only used internally */ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) @@ -54,16 +61,19 @@ void pysqlite_node_dealloc(pysqlite_Node* self) Py_TYPE(self)->tp_free((PyObject*)self); } -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) -{ - PyObject* factory; - int size = 10; +/*[clinic input] +_sqlite3.Cache.__init__ as pysqlite_cache_init - self->factory = NULL; + factory: object + size: int = 10 + / +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) { - return -1; - } +static int +pysqlite_cache_init_impl(pysqlite_Cache *self, PyObject *factory, int size) +/*[clinic end generated code: output=3a3b3e0486364359 input=5c1df5f8291291b0]*/ +{ + self->factory = NULL; /* minimum cache size is 5 entries */ if (size < 5) { @@ -112,7 +122,18 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) Py_TYPE(self)->tp_free((PyObject*)self); } -PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) +/*[clinic input] +_sqlite3.Cache.get as pysqlite_cache_get + + key: object + / + +Gets an entry from the cache or calls the factory function to produce one. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cache_get(pysqlite_Cache *self, PyObject *key) +/*[clinic end generated code: output=149ad799afafcdc8 input=07aef9c27e458441]*/ { pysqlite_Node* node; pysqlite_Node* ptr; @@ -217,7 +238,15 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) return node->data; } -PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) +/*[clinic input] +_sqlite3.Cache.display as pysqlite_cache_display + +For debugging only. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cache_display_impl(pysqlite_Cache *self) +/*[clinic end generated code: output=4010f6d5a649271c input=916727d67499366c]*/ { pysqlite_Node* ptr; PyObject* prevkey; @@ -254,10 +283,8 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) } static PyMethodDef cache_methods[] = { - {"get", (PyCFunction)pysqlite_cache_get, METH_O, - PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, - {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, - PyDoc_STR("For debugging only.")}, + PYSQLITE_CACHE_GET_METHODDEF + PYSQLITE_CACHE_DISPLAY_METHODDEF {NULL, NULL} }; diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 529010967c4f3a..9d988f9e95372b 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -65,9 +65,7 @@ extern PyTypeObject pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); void pysqlite_node_dealloc(pysqlite_Node* self); -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); void pysqlite_cache_dealloc(pysqlite_Cache* self); -PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); int pysqlite_cache_setup_types(void); diff --git a/Modules/_sqlite/clinic/cache.c.h b/Modules/_sqlite/clinic/cache.c.h new file mode 100644 index 00000000000000..c9706ad9714db3 --- /dev/null +++ b/Modules/_sqlite/clinic/cache.c.h @@ -0,0 +1,63 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static int +pysqlite_cache_init_impl(pysqlite_Cache *self, PyObject *factory, int size); + +static int +pysqlite_cache_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyObject *factory; + int size = 10; + + if (Py_IS_TYPE(self, &pysqlite_CacheType) && + !_PyArg_NoKeywords("Cache", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Cache", PyTuple_GET_SIZE(args), 1, 2)) { + goto exit; + } + factory = PyTuple_GET_ITEM(args, 0); + if (PyTuple_GET_SIZE(args) < 2) { + goto skip_optional; + } + size = _PyLong_AsInt(PyTuple_GET_ITEM(args, 1)); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = pysqlite_cache_init_impl((pysqlite_Cache *)self, factory, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cache_get__doc__, +"get($self, key, /)\n" +"--\n" +"\n" +"Gets an entry from the cache or calls the factory function to produce one."); + +#define PYSQLITE_CACHE_GET_METHODDEF \ + {"get", (PyCFunction)pysqlite_cache_get, METH_O, pysqlite_cache_get__doc__}, + +PyDoc_STRVAR(pysqlite_cache_display__doc__, +"display($self, /)\n" +"--\n" +"\n" +"For debugging only."); + +#define PYSQLITE_CACHE_DISPLAY_METHODDEF \ + {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, pysqlite_cache_display__doc__}, + +static PyObject * +pysqlite_cache_display_impl(pysqlite_Cache *self); + +static PyObject * +pysqlite_cache_display(pysqlite_Cache *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cache_display_impl(self); +} +/*[clinic end generated code: output=60204e1295b95c6a input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 0376030edc154e..5e97595fd1507a 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -368,6 +368,8 @@ static int check_cursor(pysqlite_Cursor* cur) static PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) { + _Py_IDENTIFIER(get); + pysqlite_Statement *stmt; PyObject* operation; PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; @@ -462,8 +464,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) (void)pysqlite_statement_reset(self->statement); } - Py_XSETREF(self->statement, - (pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args)); + stmt = (pysqlite_Statement *)_PyObject_CallMethodIdOneArg((PyObject *)self->connection->statement_cache, + &PyId_get, func_args); + Py_XSETREF(self->statement, stmt); Py_DECREF(func_args); if (!self->statement) { From d21accbb6ec89325f40f2a19e9ca4604c363469e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 14 Jun 2020 00:17:44 +0200 Subject: [PATCH 5/9] Convert PrepareProtocol --- Modules/_sqlite/clinic/prepare_protocol.c.h | 26 +++++++++++++++++++++ Modules/_sqlite/prepare_protocol.c | 15 +++++++++++- Modules/_sqlite/prepare_protocol.h | 1 - 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 Modules/_sqlite/clinic/prepare_protocol.c.h diff --git a/Modules/_sqlite/clinic/prepare_protocol.c.h b/Modules/_sqlite/clinic/prepare_protocol.c.h new file mode 100644 index 00000000000000..43897484f7899b --- /dev/null +++ b/Modules/_sqlite/clinic/prepare_protocol.c.h @@ -0,0 +1,26 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static int +pysqlite_prepare_protocol_init_impl(pysqlite_PrepareProtocol *self); + +static int +pysqlite_prepare_protocol_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + + if (Py_IS_TYPE(self, &pysqlite_PrepareProtocolType) && + !_PyArg_NoPositional("PrepareProtocol", args)) { + goto exit; + } + if (Py_IS_TYPE(self, &pysqlite_PrepareProtocolType) && + !_PyArg_NoKeywords("PrepareProtocol", kwargs)) { + goto exit; + } + return_value = pysqlite_prepare_protocol_init_impl((pysqlite_PrepareProtocol *)self); + +exit: + return return_value; +} +/*[clinic end generated code: output=97648812c954ace4 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 05a2ca5a652f5e..04e01200a8308d 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -22,8 +22,21 @@ */ #include "prepare_protocol.h" +#include "clinic/prepare_protocol.c.h" -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) +/*[clinic input] +module _sqlite3 +class _sqlite3.PrepareProtocol "pysqlite_PrepareProtocol *" "&pysqlite_PrepareProtocolType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4a79a14f268f3a66]*/ + +/*[clinic input] +_sqlite3.PrepareProtocol.__init__ as pysqlite_prepare_protocol_init +[clinic start generated code]*/ + +static int +pysqlite_prepare_protocol_init_impl(pysqlite_PrepareProtocol *self) +/*[clinic end generated code: output=3b31d0c14febd335 input=39127fc4f4923519]*/ { return 0; } diff --git a/Modules/_sqlite/prepare_protocol.h b/Modules/_sqlite/prepare_protocol.h index 3998a55e51cafe..7aecd263c25a1d 100644 --- a/Modules/_sqlite/prepare_protocol.h +++ b/Modules/_sqlite/prepare_protocol.h @@ -33,7 +33,6 @@ typedef struct extern PyTypeObject pysqlite_PrepareProtocolType; -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); int pysqlite_prepare_protocol_setup_types(void); From d5baf4576e6e52527e1ee92ab58bd1a7ae3536f9 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 14 Jun 2020 00:50:07 +0200 Subject: [PATCH 6/9] Convert Cursor --- Modules/_sqlite/clinic/cursor.c.h | 289 ++++++++++++++++++++++++++++++ Modules/_sqlite/cursor.c | 196 +++++++++++++------- Modules/_sqlite/cursor.h | 7 - 3 files changed, 424 insertions(+), 68 deletions(-) create mode 100644 Modules/_sqlite/clinic/cursor.c.h diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h new file mode 100644 index 00000000000000..46644a588d8222 --- /dev/null +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -0,0 +1,289 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static int +pysqlite_cursor_init_impl(pysqlite_Cursor *self, + pysqlite_Connection *connection); + +static int +pysqlite_cursor_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"connection", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "Cursor", 0}; + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + pysqlite_Connection *connection; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyObject_TypeCheck(fastargs[0], &pysqlite_ConnectionType)) { + _PyArg_BadArgument("Cursor", "argument 'connection'", (&pysqlite_ConnectionType)->tp_name, fastargs[0]); + goto exit; + } + connection = (pysqlite_Connection *)fastargs[0]; + return_value = pysqlite_cursor_init_impl((pysqlite_Cursor *)self, connection); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_execute__doc__, +"execute($self, sql, /, parameters=)\n" +"--\n" +"\n" +"Executes a SQL statement."); + +#define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ + {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_execute__doc__}, + +static PyObject * +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters); + +static PyObject * +pysqlite_cursor_execute(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "parameters", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "execute", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *sql; + PyObject *parameters = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("execute", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + parameters = args[1]; +skip_optional_pos: + return_value = pysqlite_cursor_execute_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, +"executemany($self, sql, parameters, /)\n" +"--\n" +"\n" +"Repeatedly executes a SQL statement."); + +#define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ + {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, + +static PyObject * +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters); + +static PyObject * +pysqlite_cursor_executemany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sql; + PyObject *parameters; + + if (!_PyArg_CheckPositional("executemany", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("executemany", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + sql = args[0]; + parameters = args[1]; + return_value = pysqlite_cursor_executemany_impl(self, sql, parameters); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_executescript__doc__, +"executescript($self, sql_script, /)\n" +"--\n" +"\n" +"Executes a multiple SQL statements at once. Non-standard."); + +#define PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF \ + {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_O, pysqlite_cursor_executescript__doc__}, + +PyDoc_STRVAR(pysqlite_cursor_fetchone__doc__, +"fetchone($self, /)\n" +"--\n" +"\n" +"Fetches one row from the resultset."); + +#define PYSQLITE_CURSOR_FETCHONE_METHODDEF \ + {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, pysqlite_cursor_fetchone__doc__}, + +static PyObject * +pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_fetchone(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_fetchone_impl(self); +} + +PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, +"fetchmany($self, /, size=cursor.arraysize)\n" +"--\n" +"\n" +"Fetches several rows from the resultset."); + +#define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ + {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, + +static PyObject * +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows); + +static PyObject * +pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"size", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int maxrows = self->arraysize; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + maxrows = _PyLong_AsInt(args[0]); + if (maxrows == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = pysqlite_cursor_fetchmany_impl(self, maxrows); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_fetchall__doc__, +"fetchall($self, /)\n" +"--\n" +"\n" +"Fetches all rows from the resultset."); + +#define PYSQLITE_CURSOR_FETCHALL_METHODDEF \ + {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, pysqlite_cursor_fetchall__doc__}, + +static PyObject * +pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_fetchall(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_fetchall_impl(self); +} + +PyDoc_STRVAR(pysqlite_cursor_setinputsizes__doc__, +"setinputsizes($self, sizes=None, /)\n" +"--\n" +"\n" +"Required by DB-API. Does nothing in pysqlite."); + +#define PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF \ + {"setinputsizes", (PyCFunction)(void(*)(void))pysqlite_cursor_setinputsizes, METH_FASTCALL, pysqlite_cursor_setinputsizes__doc__}, + +static PyObject * +pysqlite_cursor_setinputsizes_impl(pysqlite_Cursor *self, PyObject *sizes); + +static PyObject * +pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sizes = Py_None; + + if (!_PyArg_CheckPositional("setinputsizes", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + sizes = args[0]; +skip_optional: + return_value = pysqlite_cursor_setinputsizes_impl(self, sizes); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_setoutputsize__doc__, +"setoutputsize($self, size, column=None, /)\n" +"--\n" +"\n" +"Required by DB-API. Does nothing in pysqlite."); + +#define PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF \ + {"setoutputsize", (PyCFunction)(void(*)(void))pysqlite_cursor_setoutputsize, METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, + +static PyObject * +pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, + PyObject *column); + +static PyObject * +pysqlite_cursor_setoutputsize(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *size; + PyObject *column = Py_None; + + if (!_PyArg_CheckPositional("setoutputsize", nargs, 1, 2)) { + goto exit; + } + size = args[0]; + if (nargs < 2) { + goto skip_optional; + } + column = args[1]; +skip_optional: + return_value = pysqlite_cursor_setoutputsize_impl(self, size, column); + +exit: + return return_value; +} + +PyDoc_STRVAR(pysqlite_cursor_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Closes the cursor."); + +#define PYSQLITE_CURSOR_CLOSE_METHODDEF \ + {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, pysqlite_cursor_close__doc__}, + +static PyObject * +pysqlite_cursor_close_impl(pysqlite_Cursor *self); + +static PyObject * +pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) +{ + return pysqlite_cursor_close_impl(self); +} +/*[clinic end generated code: output=f07a9c61f46667e7 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 5e97595fd1507a..72d10be1528dbc 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -24,20 +24,29 @@ #include "cursor.h" #include "module.h" #include "util.h" +#include "clinic/cursor.c.h" + +/*[clinic input] +module _sqlite3 +class _sqlite3.Cursor "pysqlite_Cursor *" "&pysqlite_CursorType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=614fc7b8f2be9384]*/ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; -static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ - pysqlite_Connection* connection; +/*[clinic input] +_sqlite3.Cursor.__init__ as pysqlite_cursor_init - if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) - { - return -1; - } + connection: object(type='pysqlite_Connection *', subclass_of='&pysqlite_ConnectionType') +[clinic start generated code]*/ +static int +pysqlite_cursor_init_impl(pysqlite_Cursor *self, + pysqlite_Connection *connection) +/*[clinic end generated code: output=ac59dce49a809ca8 input=f0026054692c59fb]*/ +{ Py_INCREF(connection); Py_XSETREF(self->connection, connection); Py_CLEAR(self->statement); @@ -366,11 +375,10 @@ static int check_cursor(pysqlite_Cursor* cur) } static PyObject * -_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) +_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { _Py_IDENTIFIER(get); pysqlite_Statement *stmt; - PyObject* operation; PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; PyObject* parameters = NULL; @@ -381,7 +389,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) int numcols; PyObject* descriptor; PyObject* column_name; - PyObject* second_argument = NULL; sqlite_int64 lastrowid; if (!check_cursor(self)) { @@ -394,11 +401,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) Py_CLEAR(self->next_row); if (multiple) { - /* executemany() */ - if (!PyArg_ParseTuple(args, "UO", &operation, &second_argument)) { - goto error; - } - if (PyIter_Check(second_argument)) { /* iterator */ Py_INCREF(second_argument); @@ -411,11 +413,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) } } } else { - /* execute() */ - if (!PyArg_ParseTuple(args, "U|O", &operation, &second_argument)) { - goto error; - } - parameters_list = PyList_New(0); if (!parameters_list) { goto error; @@ -615,30 +612,61 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) } } -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.execute as pysqlite_cursor_execute + + sql: unicode + / + parameters: object = NULL + +Executes a SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=d81b4655c7c0bbad input=6ecc5b737d9e8219]*/ { - return _pysqlite_query_execute(self, 0, args); + return _pysqlite_query_execute(self, 0, sql, parameters); } -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.executemany as pysqlite_cursor_executemany + + sql: unicode + parameters: object + / + +Repeatedly executes a SQL statement. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, + PyObject *parameters) +/*[clinic end generated code: output=df8e2d0b7300aab6 input=a4140497fda2bf4c]*/ { - return _pysqlite_query_execute(self, 1, args); + return _pysqlite_query_execute(self, 1, sql, parameters); } +/*[clinic input] +_sqlite3.Cursor.executescript as pysqlite_cursor_executescript + + sql_script as script_obj: object + / + +Executes a multiple SQL statements at once. Non-standard. +[clinic start generated code]*/ + static PyObject * -pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) +pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) +/*[clinic end generated code: output=115a8132b0f200fe input=38c6fa6de570bb9b]*/ { _Py_IDENTIFIER(commit); - PyObject* script_obj; const char* script_cstr; sqlite3_stmt* statement; int rc; PyObject* result; - if (!PyArg_ParseTuple(args, "O", &script_obj)) { - return NULL; - } - if (!check_cursor(self)) { return NULL; } @@ -775,7 +803,15 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) return next_row; } -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.fetchone as pysqlite_cursor_fetchone + +Fetches one row from the resultset. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=4bd2eabf5baaddb0 input=e78294ec5980fdba]*/ { PyObject* row; @@ -787,19 +823,22 @@ PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) return row; } -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = {"size", NULL}; +/*[clinic input] +_sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany + + size as maxrows: int(c_default='self->arraysize') = cursor.arraysize + +Fetches several rows from the resultset. +[clinic start generated code]*/ +static PyObject * +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) +/*[clinic end generated code: output=a8ef31fea64d0906 input=d80ff999a7701ffb]*/ +{ PyObject* row; PyObject* list; - int maxrows = self->arraysize; int counter = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) { - return NULL; - } - list = PyList_New(0); if (!list) { return NULL; @@ -822,7 +861,15 @@ PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObj } } -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.fetchall as pysqlite_cursor_fetchall + +Fetches all rows from the resultset. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=d5da12aca2da4b27 input=f5d401086a8df25a]*/ { PyObject* row; PyObject* list; @@ -845,13 +892,49 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) } } -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes + + sizes: object = None + / + +Required by DB-API. Does nothing in pysqlite. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_setinputsizes_impl(pysqlite_Cursor *self, PyObject *sizes) +/*[clinic end generated code: output=a06c12790bd05f2e input=d058d07e828431de]*/ { - /* don't care, return None */ Py_RETURN_NONE; } -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) +/*[clinic input] +_sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize + + size: object + column: object = None + / + +Required by DB-API. Does nothing in pysqlite. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, + PyObject *column) +/*[clinic end generated code: output=018d7e9129d45efe input=077b017da58b9389]*/ +{ + Py_RETURN_NONE; +} + +/*[clinic input] +_sqlite3.Cursor.close as pysqlite_cursor_close + +Closes the cursor. +[clinic start generated code]*/ + +static PyObject * +pysqlite_cursor_close_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ { if (!self->connection) { PyErr_SetString(pysqlite_ProgrammingError, @@ -873,24 +956,15 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) } static PyMethodDef cursor_methods[] = { - {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement.")}, - {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement.")}, - {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, - {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, - PyDoc_STR("Fetches one row from the resultset.")}, - {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Fetches several rows from the resultset.")}, - {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, - PyDoc_STR("Fetches all rows from the resultset.")}, - {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, - PyDoc_STR("Closes the cursor.")}, - {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, - {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, + PYSQLITE_CURSOR_CLOSE_METHODDEF + PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF + PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF + PYSQLITE_CURSOR_EXECUTE_METHODDEF + PYSQLITE_CURSOR_FETCHALL_METHODDEF + PYSQLITE_CURSOR_FETCHMANY_METHODDEF + PYSQLITE_CURSOR_FETCHONE_METHODDEF + PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF + PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF {NULL, NULL} }; diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index 4a20e756f7829d..7f04ecde2edb06 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -54,15 +54,8 @@ typedef struct extern PyTypeObject pysqlite_CursorType; -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self); PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self); -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); int pysqlite_cursor_setup_types(void); From 144d84ad63b286bb56396beadc9fe528f20eec88 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 14 Jun 2020 21:09:30 +0200 Subject: [PATCH 7/9] Convert sqlite3.connect() and Connection.__init__() --- Modules/_sqlite/clinic/connection.c.h | 103 ++++++++++++++++++++++- Modules/_sqlite/clinic/module.c.h | 114 +++++++++++++++++++++++++- Modules/_sqlite/connection.c | 43 +++++----- Modules/_sqlite/connection.h | 1 - Modules/_sqlite/module.c | 104 ++++++++++++++--------- 5 files changed, 299 insertions(+), 66 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index ddae4a5b108817..1cb7d0739632dc 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -2,6 +2,107 @@ preserve [clinic start generated code]*/ +static int +pysqlite_connection_init_impl(pysqlite_Connection *self, + PyObject *database_obj, double timeout, + int detect_types, PyObject *isolation_level, + int check_same_thread, PyObject *factory, + int cached_statements, int uri); + +static int +pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "Connection", 0}; + PyObject *argsbuf[8]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; + PyObject *database_obj; + double timeout = 5.0; + int detect_types = 0; + PyObject *isolation_level = NULL; + int check_same_thread = 1; + PyObject *factory = (PyObject*)&pysqlite_ConnectionType; + int cached_statements = 100; + int uri = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_FSConverter(fastargs[0], &database_obj)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + if (PyFloat_CheckExact(fastargs[1])) { + timeout = PyFloat_AS_DOUBLE(fastargs[1]); + } + else + { + timeout = PyFloat_AsDouble(fastargs[1]); + if (timeout == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + detect_types = _PyLong_AsInt(fastargs[2]); + if (detect_types == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[3]) { + isolation_level = fastargs[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[4]) { + check_same_thread = _PyLong_AsInt(fastargs[4]); + if (check_same_thread == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[5]) { + factory = fastargs[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[6]) { + cached_statements = _PyLong_AsInt(fastargs[6]); + if (cached_statements == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + uri = PyObject_IsTrue(fastargs[7]); + if (uri < 0) { + goto exit; + } +skip_optional_pos: + return_value = pysqlite_connection_init_impl((pysqlite_Connection *)self, database_obj, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri); + +exit: + return return_value; +} + PyDoc_STRVAR(pysqlite_connection_cursor__doc__, "cursor($self, /, factory=)\n" "--\n" @@ -682,4 +783,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss #ifndef PYSQLITE_CONNECTION_BACKUP_METHODDEF #define PYSQLITE_CONNECTION_BACKUP_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_BACKUP_METHODDEF) */ -/*[clinic end generated code: output=2f69688f7e0cf5b3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d1fb1f48710a3cd4 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index af9d39edb5168f..a4f5639e1e0237 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -2,6 +2,118 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(pysqlite_connect__doc__, +"connect($module, /, database, timeout=5.0, detect_types=0,\n" +" isolation_level=, check_same_thread=1,\n" +" factory=ConnectionType, cached_statements=100, uri=False)\n" +"--\n" +"\n" +"Opens a connection to the SQLite database file database.\n" +"\n" +"You can use \":memory:\" to open a database connection to a database that resides\n" +"in RAM instead of on disk."); + +#define PYSQLITE_CONNECT_METHODDEF \ + {"connect", (PyCFunction)(void(*)(void))pysqlite_connect, METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__}, + +static PyObject * +pysqlite_connect_impl(PyObject *module, PyObject *database, double timeout, + int detect_types, PyObject *isolation_level, + int check_same_thread, PyObject *factory, + int cached_statements, int uri); + +static PyObject * +pysqlite_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "connect", 0}; + PyObject *argsbuf[8]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *database; + double timeout = 5.0; + int detect_types = 0; + PyObject *isolation_level = NULL; + int check_same_thread = 1; + PyObject *factory = (PyObject*)&pysqlite_ConnectionType; + int cached_statements = 100; + int uri = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 8, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_FSConverter(args[0], &database)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (PyFloat_CheckExact(args[1])) { + timeout = PyFloat_AS_DOUBLE(args[1]); + } + else + { + timeout = PyFloat_AsDouble(args[1]); + if (timeout == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + detect_types = _PyLong_AsInt(args[2]); + if (detect_types == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + isolation_level = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + check_same_thread = _PyLong_AsInt(args[4]); + if (check_same_thread == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + factory = args[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[6]) { + cached_statements = _PyLong_AsInt(args[6]); + if (cached_statements == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + uri = PyObject_IsTrue(args[7]); + if (uri < 0) { + goto exit; + } +skip_optional_pos: + return_value = pysqlite_connect_impl(module, database, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri); + +exit: + return return_value; +} + PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, statement, /)\n" "--\n" @@ -213,4 +325,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF #define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF #endif /* !defined(PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF) */ -/*[clinic end generated code: output=2f740fe39ac0ec71 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5e0bb0b26046264e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 30c8b5672a39fd..e6bd40bf50cd7a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -58,33 +58,30 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = { - "database", "timeout", "detect_types", "isolation_level", - "check_same_thread", "factory", "cached_statements", "uri", - NULL - }; +/*[clinic input] +_sqlite3.Connection.__init__ as pysqlite_connection_init + + database as database_obj: object(converter='PyUnicode_FSConverter') + timeout: double = 5.0 + detect_types: int = 0 + isolation_level: object = NULL + check_same_thread: int = 1 + factory: object(c_default='(PyObject*)&pysqlite_ConnectionType') = ConnectionType + cached_statements: int = 100 + uri: bool = False +[clinic start generated code]*/ +static int +pysqlite_connection_init_impl(pysqlite_Connection *self, + PyObject *database_obj, double timeout, + int detect_types, PyObject *isolation_level, + int check_same_thread, PyObject *factory, + int cached_statements, int uri) +/*[clinic end generated code: output=dc19df1c0e2b7b77 input=f7f8a772a2df3427]*/ +{ const char* database; - PyObject* database_obj; - int detect_types = 0; - PyObject* isolation_level = NULL; - PyObject* factory = NULL; - int check_same_thread = 1; - int cached_statements = 100; - int uri = 0; - double timeout = 5.0; int rc; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|diOiOip", kwlist, - PyUnicode_FSConverter, &database_obj, &timeout, &detect_types, - &isolation_level, &check_same_thread, - &factory, &cached_statements, &uri)) - { - return -1; - } - database = PyBytes_AsString(database_obj); self->initialized = 1; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 8ea7d9cc3dee99..967fea258f4785 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -112,7 +112,6 @@ PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); void pysqlite_connection_dealloc(pysqlite_Connection* self); PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor); int pysqlite_check_thread(pysqlite_Connection* self); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index b7a3ac2eeea450..85a26e92ebd11d 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -56,58 +56,83 @@ PyObject* _pysqlite_converters = NULL; int _pysqlite_enable_callback_tracebacks = 0; int pysqlite_BaseTypeAdapted = 0; -static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* - kwargs) -{ - /* Python seems to have no way of extracting a single keyword-arg at - * C-level, so this code is redundant with the one in connection_init in - * connection.c and must always be copied from there ... */ +/* Python seems to have no way of extracting a single keyword-arg at + * C-level, so this code is redundant with the one in connection_init in + * connection.c and must always be copied from there ... */ +/*[clinic input] +_sqlite3.connect as pysqlite_connect - static char *kwlist[] = { - "database", "timeout", "detect_types", "isolation_level", - "check_same_thread", "factory", "cached_statements", "uri", - NULL - }; - PyObject* database; - int detect_types = 0; - PyObject* isolation_level; - PyObject* factory = NULL; - int check_same_thread = 1; - int cached_statements; - int uri = 0; - double timeout = 5.0; + database: object(converter='PyUnicode_FSConverter') + timeout: double = 5.0 + detect_types: int = 0 + isolation_level: object = NULL + check_same_thread: int = 1 + factory: object(c_default='(PyObject*)&pysqlite_ConnectionType') = ConnectionType + cached_statements: int = 100 + uri: bool = False + +Opens a connection to the SQLite database file database. +You can use ":memory:" to open a database connection to a database that resides +in RAM instead of on disk. +[clinic start generated code]*/ + +static PyObject * +pysqlite_connect_impl(PyObject *module, PyObject *database, double timeout, + int detect_types, PyObject *isolation_level, + int check_same_thread, PyObject *factory, + int cached_statements, int uri) +/*[clinic end generated code: output=450ac9078b4868bb input=f9f43e3bd4497723]*/ +{ + PyObject* obj_timeout; + PyObject* obj_detect_types; + PyObject* obj_check_same_thread; + PyObject* obj_cached_statements; + PyObject* obj_uri; PyObject* result; + int decref_isolation_level = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOip", kwlist, - &database, &timeout, &detect_types, - &isolation_level, &check_same_thread, - &factory, &cached_statements, &uri)) - { + if (PySys_Audit("sqlite3.connect", "O", database) < 0) { return NULL; } - if (factory == NULL) { - factory = (PyObject*)&pysqlite_ConnectionType; + if (!isolation_level) { + isolation_level = PyUnicode_FromString(""); + if (!isolation_level) { + return NULL; + } + decref_isolation_level = 1; } - if (PySys_Audit("sqlite3.connect", "O", database) < 0) { - return NULL; + obj_timeout = PyFloat_FromDouble(timeout); + obj_detect_types = PyLong_FromLong(detect_types); + obj_check_same_thread = PyLong_FromLong(check_same_thread); + obj_cached_statements = PyLong_FromLong(cached_statements); + obj_uri = PyBool_FromLong(uri); + + result = PyObject_CallFunctionObjArgs(factory, + database, + obj_timeout, + obj_detect_types, + isolation_level, + obj_check_same_thread, + factory, + obj_cached_statements, + obj_uri, + NULL); + if (decref_isolation_level) { + Py_DECREF(isolation_level); } - - result = PyObject_Call(factory, args, kwargs); + Py_XDECREF(database); + Py_XDECREF(obj_timeout); + Py_XDECREF(obj_detect_types); + Py_XDECREF(obj_check_same_thread); + Py_XDECREF(obj_cached_statements); + Py_XDECREF(obj_uri); return result; } -PyDoc_STRVAR(module_connect_doc, -"connect(database[, timeout, detect_types, isolation_level,\n\ - check_same_thread, factory, cached_statements, uri])\n\ -\n\ -Opens a connection to the SQLite database file *database*. You can use\n\ -\":memory:\" to open a database connection to a database that resides in\n\ -RAM instead of on disk."); - /*[clinic input] _sqlite3.complete_statement as pysqlite_complete_statement @@ -276,10 +301,9 @@ static void converters_init(PyObject* dict) } static PyMethodDef module_methods[] = { - {"connect", (PyCFunction)(void(*)(void))module_connect, - METH_VARARGS | METH_KEYWORDS, module_connect_doc}, PYSQLITE_ADAPT_METHODDEF PYSQLITE_COMPLETE_STATEMENT_METHODDEF + PYSQLITE_CONNECT_METHODDEF PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF PYSQLITE_REGISTER_ADAPTER_METHODDEF From dab5c43418056d273e47f33574f9c056fe58a49e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 14 Jun 2020 21:21:30 +0200 Subject: [PATCH 8/9] Add NEWS --- .../NEWS.d/next/Library/2020-06-12-12-05-59.bpo-40956._tvsZ7.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-06-12-12-05-59.bpo-40956._tvsZ7.rst diff --git a/Misc/NEWS.d/next/Library/2020-06-12-12-05-59.bpo-40956._tvsZ7.rst b/Misc/NEWS.d/next/Library/2020-06-12-12-05-59.bpo-40956._tvsZ7.rst new file mode 100644 index 00000000000000..59f41275c652f1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-12-12-05-59.bpo-40956._tvsZ7.rst @@ -0,0 +1 @@ +Use Argument Clinic in :mod:`sqlite3` From 822d50fd793df7b72bcf13891d49e66bddc190e5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 11:19:19 +0200 Subject: [PATCH 9/9] Sync clinic with master --- Modules/_sqlite/clinic/connection.c.h | 18 +++++------------- Modules/_sqlite/clinic/module.c.h | 10 +--------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 1cb7d0739632dc..dffb7ca30231fc 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -369,7 +369,7 @@ PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, #define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ {"set_trace_callback", (PyCFunction)pysqlite_connection_set_trace_callback, METH_O, pysqlite_connection_set_trace_callback__doc__}, -#if defined(HAVE_LOAD_EXTENSION) +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, "enable_load_extension($self, enable, /)\n" @@ -400,9 +400,9 @@ pysqlite_connection_enable_load_extension(pysqlite_Connection *self, PyObject *a return return_value; } -#endif /* defined(HAVE_LOAD_EXTENSION) */ +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ -#if defined(HAVE_LOAD_EXTENSION) +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, "load_extension($self, name, /)\n" @@ -442,7 +442,7 @@ pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *arg) return return_value; } -#endif /* defined(HAVE_LOAD_EXTENSION) */ +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ PyDoc_STRVAR(pysqlite_connection_execute__doc__, "execute($self, sql, /, parameters=)\n" @@ -575,8 +575,6 @@ pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(igno return pysqlite_connection_iterdump_impl(self); } -#if defined(HAVE_BACKUP_API) - PyDoc_STRVAR(pysqlite_connection_backup__doc__, "backup($self, /, target=, *, pages=-1, progress=None,\n" " name=\'main\', sleep=0.25)\n" @@ -677,8 +675,6 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ return return_value; } -#endif /* defined(HAVE_BACKUP_API) */ - PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, "create_collation($self, name, callback, /)\n" "--\n" @@ -779,8 +775,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ - -#ifndef PYSQLITE_CONNECTION_BACKUP_METHODDEF - #define PYSQLITE_CONNECTION_BACKUP_METHODDEF -#endif /* !defined(PYSQLITE_CONNECTION_BACKUP_METHODDEF) */ -/*[clinic end generated code: output=d1fb1f48710a3cd4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=578e5f247210bbdf input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index a4f5639e1e0237..76f6bb63f76569 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -151,8 +151,6 @@ pysqlite_complete_statement(PyObject *module, PyObject *arg) return return_value; } -#if defined(HAVE_SHARED_CACHE) - PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, "enable_shared_cache($module, enable, /)\n" "--\n" @@ -183,8 +181,6 @@ pysqlite_enable_shared_cache(PyObject *module, PyObject *arg) return return_value; } -#endif /* defined(HAVE_SHARED_CACHE) */ - PyDoc_STRVAR(pysqlite_register_adapter__doc__, "register_adapter($module, type, caster, /)\n" "--\n" @@ -321,8 +317,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } - -#ifndef PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF - #define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF -#endif /* !defined(PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF) */ -/*[clinic end generated code: output=5e0bb0b26046264e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=79068baf73b272f8 input=a9049054013a1b77]*/ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy