diff options
Diffstat (limited to 'Modules/_sqlite')
| -rw-r--r-- | Modules/_sqlite/cache.c | 1 | ||||
| -rw-r--r-- | Modules/_sqlite/connection.c | 99 | ||||
| -rw-r--r-- | Modules/_sqlite/cursor.c | 17 | ||||
| -rw-r--r-- | Modules/_sqlite/module.c | 16 | ||||
| -rw-r--r-- | Modules/_sqlite/prepare_protocol.c | 1 | ||||
| -rw-r--r-- | Modules/_sqlite/row.c | 1 | ||||
| -rw-r--r-- | Modules/_sqlite/sqlitecompat.h | 63 | ||||
| -rw-r--r-- | Modules/_sqlite/statement.c | 3 | ||||
| -rw-r--r-- | Modules/_sqlite/util.c | 2 |
9 files changed, 98 insertions, 105 deletions
diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 3693363..3689a4e 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -21,7 +21,6 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include "sqlitecompat.h" #include "cache.h" #include <limits.h> diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 451ea24..7365a88 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -29,7 +29,6 @@ #include "cursor.h" #include "prepare_protocol.h" #include "util.h" -#include "sqlitecompat.h" #include "pythread.h" @@ -42,6 +41,8 @@ #endif #endif +_Py_IDENTIFIER(cursor); + static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level); static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); @@ -60,7 +61,11 @@ static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int 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", NULL, NULL}; + static char *kwlist[] = { + "database", "timeout", "detect_types", "isolation_level", + "check_same_thread", "factory", "cached_statements", "uri", + NULL + }; char* database; int detect_types = 0; @@ -68,11 +73,14 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject 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, "s|diOiOi", kwlist, - &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOip", kwlist, + &database, &timeout, &detect_types, + &isolation_level, &check_same_thread, + &factory, &cached_statements, &uri)) { return -1; } @@ -91,8 +99,19 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject Py_INCREF(&PyUnicode_Type); self->text_factory = (PyObject*)&PyUnicode_Type; +#ifdef SQLITE_OPEN_URI + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_open_v2(database, &self->db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + (uri ? SQLITE_OPEN_URI : 0), NULL); +#else + if (uri) { + PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported"); + return -1; + } Py_BEGIN_ALLOW_THREADS rc = sqlite3_open(database, &self->db); +#endif Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { @@ -679,6 +698,8 @@ void _pysqlite_final_callback(sqlite3_context* context) PyObject** aggregate_instance; _Py_IDENTIFIER(finalize); int ok; + PyObject *exception, *value, *tb; + int restore; #ifdef WITH_THREAD PyGILState_STATE threadstate; @@ -694,7 +715,12 @@ void _pysqlite_final_callback(sqlite3_context* context) goto error; } + /* Keep the exception (if any) of the last call to step() */ + PyErr_Fetch(&exception, &value, &tb); + restore = 1; + function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, ""); + Py_DECREF(*aggregate_instance); ok = 0; @@ -709,6 +735,17 @@ void _pysqlite_final_callback(sqlite3_context* context) PyErr_Clear(); } _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); +#if SQLITE_VERSION_NUMBER < 3003003 + /* with old SQLite versions, _sqlite3_result_error() sets a new Python + exception, so don't restore the previous exception */ + restore = 0; +#endif + } + + if (restore) { + /* Restore the exception (if any) of the last call to step(), + but clear also the current exception if finalize() failed */ + PyErr_Restore(exception, value, tb); } error: @@ -859,22 +896,29 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co gilstate = PyGILState_Ensure(); #endif + ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); - if (!ret) { - if (_enable_callback_tracebacks) { + if (ret == NULL) { + if (_enable_callback_tracebacks) PyErr_Print(); - } else { + else PyErr_Clear(); - } rc = SQLITE_DENY; - } else { + } + else { if (PyLong_Check(ret)) { rc = _PyLong_AsInt(ret); - if (rc == -1 && PyErr_Occurred()) + if (rc == -1 && PyErr_Occurred()) { + if (_enable_callback_tracebacks) + PyErr_Print(); + else + PyErr_Clear(); rc = SQLITE_DENY; - } else { + } + } + else { rc = SQLITE_DENY; } Py_DECREF(ret); @@ -1187,9 +1231,8 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py return NULL; } - if (!PyArg_ParseTuple(args, "O", &sql)) { + if (!PyArg_ParseTuple(args, "O", &sql)) return NULL; - } _pysqlite_drop_unused_statement_references(self); @@ -1205,7 +1248,6 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py statement->in_weakreflist = NULL; rc = pysqlite_statement_create(statement, self, sql); - if (rc != SQLITE_OK) { if (rc == PYSQLITE_TOO_MUCH_SQL) { PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time."); @@ -1215,25 +1257,23 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py (void)pysqlite_statement_reset(statement); _pysqlite_seterror(self->db, NULL); } + goto error; + } - Py_CLEAR(statement); - } else { - weakref = PyWeakref_NewRef((PyObject*)statement, NULL); - if (!weakref) { - Py_CLEAR(statement); - goto error; - } - - if (PyList_Append(self->statements, weakref) != 0) { - Py_CLEAR(weakref); - goto error; - } - + weakref = PyWeakref_NewRef((PyObject*)statement, NULL); + if (weakref == NULL) + goto error; + if (PyList_Append(self->statements, weakref) != 0) { Py_DECREF(weakref); + goto error; } + Py_DECREF(weakref); -error: return (PyObject*)statement; + +error: + Py_DECREF(statement); + return NULL; } PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) @@ -1241,7 +1281,6 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; - _Py_IDENTIFIER(cursor); cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { @@ -1271,7 +1310,6 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; - _Py_IDENTIFIER(cursor); cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { @@ -1301,7 +1339,6 @@ PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; - _Py_IDENTIFIER(cursor); cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 4999415..8d10890 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -24,7 +24,6 @@ #include "cursor.h" #include "module.h" #include "util.h" -#include "sqlitecompat.h" PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); @@ -339,6 +338,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { converted = PyUnicode_FromStringAndSize(val_str, nbytes); if (!converted) { +#ifdef Py_DEBUG + /* in debug mode, type_call() fails with an assertion + error if an exception is set when it is called */ + PyErr_Clear(); +#endif colname = sqlite3_column_name(self->statement->st, i); if (!colname) { colname = "<unknown column name>"; @@ -867,10 +871,15 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) } next_row_tuple = self->next_row; + assert(next_row_tuple != NULL); self->next_row = NULL; if (self->row_factory != Py_None) { next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); + if (next_row == NULL) { + self->next_row = next_row_tuple; + return NULL; + } Py_DECREF(next_row_tuple); } else { next_row = next_row_tuple; @@ -887,6 +896,12 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (rc == SQLITE_ROW) { self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) { + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + _pysqlite_seterror(self->connection->db, NULL); + return NULL; + } } } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index bea6d6a..7a7e860 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -50,19 +50,26 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* * C-level, so this code is redundant with the one in connection_init in * connection.c and must always be copied from there ... */ - static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; + static char *kwlist[] = { + "database", "timeout", "detect_types", "isolation_level", + "check_same_thread", "factory", "cached_statements", "uri", + NULL + }; char* 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; PyObject* result; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist, - &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOip", kwlist, + &database, &timeout, &detect_types, + &isolation_level, &check_same_thread, + &factory, &cached_statements, &uri)) { return NULL; } @@ -77,7 +84,8 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* } PyDoc_STRVAR(module_connect_doc, -"connect(database[, timeout, isolation_level, detect_types, factory])\n\ +"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\ diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index fc68874..f2c85f9 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -21,7 +21,6 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include "sqlitecompat.h" #include "prepare_protocol.h" int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index b50658c..14c148e 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -23,7 +23,6 @@ #include "row.h" #include "cursor.h" -#include "sqlitecompat.h" void pysqlite_row_dealloc(pysqlite_Row* self) { diff --git a/Modules/_sqlite/sqlitecompat.h b/Modules/_sqlite/sqlitecompat.h deleted file mode 100644 index cf20f16..0000000 --- a/Modules/_sqlite/sqlitecompat.h +++ /dev/null @@ -1,63 +0,0 @@ -/* sqlitecompat.h - compatibility macros - * - * Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de> - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "Python.h" - -#ifndef PYSQLITE_COMPAT_H -#define PYSQLITE_COMPAT_H - -/* define Py_ssize_t for pre-2.5 versions of Python */ - -#if PY_VERSION_HEX < 0x02050000 -typedef int Py_ssize_t; -typedef int (*lenfunc)(PyObject*); -#endif - - -/* define PyDict_CheckExact for pre-2.4 versions of Python */ -#ifndef PyDict_CheckExact -#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type) -#endif - -/* define Py_CLEAR for pre-2.4 versions of Python */ -#ifndef Py_CLEAR -#define Py_CLEAR(op) \ - do { \ - if (op) { \ - PyObject *tmp = (PyObject *)(op); \ - (op) = NULL; \ - Py_DECREF(tmp); \ - } \ - } while (0) -#endif - -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, -#endif - -#ifndef Py_TYPE -#define Py_TYPE(ob) ((ob)->ob_type) -#endif - -#endif diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 471a067..b056d8b 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -27,7 +27,6 @@ #include "microprotocols.h" #include "prepare_protocol.h" #include "util.h" -#include "sqlitecompat.h" /* prototypes */ static int pysqlite_check_remaining_sql(const char* tail); @@ -249,7 +248,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para current_param = PyDict_GetItemString(parameters, binding_name); Py_XINCREF(current_param); } else { - current_param = PyMapping_GetItemString(parameters, (char*)binding_name); + current_param = PyMapping_GetItemString(parameters, binding_name); } if (!current_param) { PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index d88bc3f..312fe3b 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -132,7 +132,7 @@ _pysqlite_long_from_int64(sqlite_int64 value) } # endif #endif - return PyLong_FromLong(value); + return PyLong_FromLong(Py_SAFE_DOWNCAST(value, sqlite_int64, long)); } sqlite_int64 |
