Metadata-Version: 1.1
Name: pysqlite3
-Version: 0.2.1
+Version: 0.2.2
Summary: DB-API 2.0 interface for Sqlite 3.x
Home-page: https://github.com/coleifer/pysqlite3
Author: Charles Leifer
+++ /dev/null
-# Mimic the sqlite3 console shell's .dump command
-# Author: Paul Kippes <kippesp@gmail.com>
-
-# Every identifier in sql is quoted based on a comment in sqlite
-# documentation "SQLite adds new keywords from time to time when it
-# takes on new features. So to prevent your code from being broken by
-# future enhancements, you should normally quote any identifier that
-# is an English language word, even if you do not have to."
-
-def _iterdump(connection):
- """
- Returns an iterator to the dump of the database in an SQL text format.
-
- Used to produce an SQL dump of the database. Useful to save an in-memory
- database for later restoration. This function should not be called
- directly but instead called from the Connection method, iterdump().
- """
-
- cu = connection.cursor()
- yield('BEGIN TRANSACTION;')
-
- # sqlite_master table contains the SQL CREATE statements for the database.
- q = """
- SELECT "name", "type", "sql"
- FROM "sqlite_master"
- WHERE "sql" NOT NULL AND
- "type" == 'table'
- ORDER BY "name"
- """
- schema_res = cu.execute(q)
- for table_name, type, sql in schema_res.fetchall():
- if table_name == 'sqlite_sequence':
- yield('DELETE FROM "sqlite_sequence";')
- elif table_name == 'sqlite_stat1':
- yield('ANALYZE "sqlite_master";')
- elif table_name.startswith('sqlite_'):
- continue
- # NOTE: Virtual table support not implemented
- #elif sql.startswith('CREATE VIRTUAL TABLE'):
- # qtable = table_name.replace("'", "''")
- # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\
- # "VALUES('table','{0}','{0}',0,'{1}');".format(
- # qtable,
- # sql.replace("''")))
- else:
- yield('{0};'.format(sql))
-
- # Build the insert statement for each row of the current table
- table_name_ident = table_name.replace('"', '""')
- res = cu.execute('PRAGMA table_info("{0}")'.format(table_name_ident))
- column_names = [str(table_info[1]) for table_info in res.fetchall()]
- q = """SELECT 'INSERT INTO "{0}" VALUES({1})' FROM "{0}";""".format(
- table_name_ident,
- ",".join("""'||quote("{0}")||'""".format(col.replace('"', '""')) for col in column_names))
- query_res = cu.execute(q)
- for row in query_res:
- yield("{0};".format(row[0]))
-
- # Now when the type is 'index', 'trigger', or 'view'
- q = """
- SELECT "name", "type", "sql"
- FROM "sqlite_master"
- WHERE "sql" NOT NULL AND
- "type" IN ('index', 'trigger', 'view')
- """
- schema_res = cu.execute(q)
- for name, type, sql in schema_res.fetchall():
- yield('{0};'.format(sql))
-
- yield('COMMIT;')
Metadata-Version: 1.1
Name: pysqlite3
-Version: 0.2.1
+Version: 0.2.2
Summary: DB-API 2.0 interface for Sqlite 3.x
Home-page: https://github.com/coleifer/pysqlite3
Author: Charles Leifer
setup.py
lib/__init__.py
lib/dbapi2.py
-lib/dump.py
pysqlite3.egg-info/PKG-INFO
pysqlite3.egg-info/SOURCES.txt
pysqlite3.egg-info/dependency_links.txt
# If you need to change anything, it should be enough to change setup.cfg.
PACKAGE_NAME = 'pysqlite3'
-VERSION = '0.2.1'
+VERSION = '0.2.2'
# define sqlite sources
sources = [os.path.join('src', source)
pysqlite_Node* ptr;
PyObject* data;
- node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key);
+ node = (pysqlite_Node*)PyDict_GetItemWithError(self->mapping, key);
if (node) {
/* an entry for this key already exists in the cache */
}
ptr->prev = node;
}
- } else {
+ }
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
+ else {
/* There is no entry for this key in the cache, yet. We'll insert a new
* entry in the cache, and make space if necessary by throwing the
* least used item out of the cache. */
#ifndef PYSQLITE_CACHE_H
#define PYSQLITE_CACHE_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
/* The LRU cache is implemented as a combination of a doubly-linked with a
NULL
};
-static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level);
+static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored));
static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
static char *kwlist[] = {
"database", "timeout", "detect_types", "isolation_level",
"check_same_thread", "factory", "cached_statements", "uri", "flags",
- "vfs",
- NULL
+ "vfs", NULL
};
char* database;
Py_INCREF(&PyUnicode_Type);
Py_XSETREF(self->text_factory, (PyObject*)&PyUnicode_Type);
-#ifdef SQLITE_OPEN_URI
- Py_BEGIN_ALLOW_THREADS
- rc = sqlite3_open_v2(database, &self->db,
- flags | (uri ? SQLITE_OPEN_URI : 0), vfs);
-#else
+#ifndef SQLITE_OPEN_URI
if (uri) {
PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported");
return -1;
}
- Py_BEGIN_ALLOW_THREADS
- rc = sqlite3_open_v2(database, &self->db, flags, vfs);
#endif
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_open_v2(database, &self->db,
+ flags | (uri ? SQLITE_OPEN_URI : 0), vfs);
Py_END_ALLOW_THREADS
Py_DECREF(database_obj);
Py_INCREF(isolation_level);
}
Py_CLEAR(self->isolation_level);
- if (pysqlite_connection_set_isolation_level(self, isolation_level) < 0) {
+ if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) < 0) {
Py_DECREF(isolation_level);
return -1;
}
}
self->check_same_thread = check_same_thread;
- Py_XSETREF(self->function_pinboard, PyDict_New());
- if (!self->function_pinboard) {
- return -1;
- }
+ self->function_pinboard_trace_callback = NULL;
+ self->function_pinboard_progress_handler = NULL;
+ self->function_pinboard_authorizer_cb = NULL;
Py_XSETREF(self->collations, PyDict_New());
if (!self->collations) {
/* Clean up if user has not called .close() explicitly. */
if (self->db) {
- Py_BEGIN_ALLOW_THREADS
SQLITE3_CLOSE(self->db);
- Py_END_ALLOW_THREADS
}
Py_XDECREF(self->isolation_level);
- Py_XDECREF(self->function_pinboard);
+ Py_XDECREF(self->function_pinboard_trace_callback);
+ Py_XDECREF(self->function_pinboard_progress_handler);
+ Py_XDECREF(self->function_pinboard_authorizer_cb);
Py_XDECREF(self->row_factory);
Py_XDECREF(self->text_factory);
Py_XDECREF(self->collations);
pysqlite_do_all_statements(self, ACTION_FINALIZE, 1);
if (self->db) {
- Py_BEGIN_ALLOW_THREADS
rc = SQLITE3_CLOSE(self->db);
- Py_END_ALLOW_THREADS
if (rc != SQLITE_OK) {
_pysqlite_seterror(self->db, NULL);
Py_DECREF(py_retval);
}
if (!ok) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
if (PyErr_Occurred()) {
*aggregate_instance = 0;
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
Py_DECREF(args);
if (!function_result) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
Py_DECREF(function_result);
}
if (!ok) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
Py_DECREF(function_result);
}
if (!ok) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
Py_DECREF(args);
if (!function_result) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
Py_SETREF(self->cursors, new_list);
}
+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", NULL, NULL};
+ static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL};
PyObject* func;
char* name;
int narg;
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", kwlist,
- &name, &narg, &func))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|p", kwlist,
+ &name, &narg, &func, &deterministic))
{
return NULL;
}
- rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _pysqlite_func_callback, NULL, NULL);
+ if (deterministic) {
+#if SQLITE_VERSION_NUMBER < 3008003
+ PyErr_SetString(pysqlite_NotSupportedError,
+ "deterministic=True requires SQLite 3.8.3 or higher");
+ return NULL;
+#else
+ if (sqlite3_libversion_number() < 3008003) {
+ PyErr_SetString(pysqlite_NotSupportedError,
+ "deterministic=True requires SQLite 3.8.3 or higher");
+ return NULL;
+ }
+ flags |= SQLITE_DETERMINISTIC;
+#endif
+ }
+ Py_INCREF(func);
+ rc = sqlite3_create_function_v2(self->db,
+ name,
+ narg,
+ flags,
+ (void*)func,
+ _pysqlite_func_callback,
+ NULL,
+ NULL,
+ &_destructor);
if (rc != SQLITE_OK) {
/* Workaround for SQLite bug: no error code or string is available here */
PyErr_SetString(pysqlite_OperationalError, "Error creating function");
return NULL;
- } else {
- if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1)
- return NULL;
-
- Py_RETURN_NONE;
}
+ Py_RETURN_NONE;
}
PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
return NULL;
}
- rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_pysqlite_step_callback, &_pysqlite_final_callback);
+ Py_INCREF(aggregate_class);
+ rc = sqlite3_create_function_v2(self->db,
+ name,
+ n_arg,
+ SQLITE_UTF8,
+ (void*)aggregate_class,
+ 0,
+ &_pysqlite_step_callback,
+ &_pysqlite_final_callback,
+ &_destructor);
+
if (rc != SQLITE_OK) {
/* Workaround for SQLite bug: no error code or string is available here */
PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate");
return NULL;
- } else {
- if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1)
- return NULL;
-
- Py_RETURN_NONE;
}
+ Py_RETURN_NONE;
}
#ifdef HAVE_WINDOW_FUNCTION
+
PyObject* pysqlite_connection_create_window_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
{
PyObject* window_function_class;
return NULL;
}
+ Py_INCREF(window_function_class);
rc = sqlite3_create_window_function(
self->db,
name,
&_pysqlite_final_callback,
&_pysqlite_value_callback,
&_pysqlite_inverse_callback,
- NULL);
+ &_destructor);
if (rc != SQLITE_OK) {
/* Workaround for SQLite bug: no error code or string is available here */
PyErr_SetString(pysqlite_OperationalError, "Error creating window function");
return NULL;
- } else {
- if (PyDict_SetItem(self->function_pinboard, window_function_class, Py_None) == -1)
- return NULL;
-
- Py_RETURN_NONE;
}
+ Py_RETURN_NONE;
}
#endif
+
static int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source)
{
PyObject *ret;
ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
if (ret == NULL) {
- if (_enable_callback_tracebacks)
+ if (_pysqlite_enable_callback_tracebacks)
PyErr_Print();
else
PyErr_Clear();
if (PyLong_Check(ret)) {
rc = _PyLong_AsInt(ret);
if (rc == -1 && PyErr_Occurred()) {
- if (_enable_callback_tracebacks)
+ if (_pysqlite_enable_callback_tracebacks)
PyErr_Print();
else
PyErr_Clear();
ret = _PyObject_CallNoArg((PyObject*)user_arg);
if (!ret) {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
if (ret) {
Py_DECREF(ret);
} else {
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
}
rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb);
-
if (rc != SQLITE_OK) {
PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback");
+ Py_XSETREF(self->function_pinboard_authorizer_cb, NULL);
return NULL;
} else {
- if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1)
- return NULL;
-
- Py_RETURN_NONE;
+ Py_INCREF(authorizer_cb);
+ Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb);
}
+ Py_RETURN_NONE;
}
static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
if (progress_handler == Py_None) {
/* None clears the progress handler previously set */
sqlite3_progress_handler(self->db, 0, 0, (void*)0);
+ Py_XSETREF(self->function_pinboard_progress_handler, NULL);
} else {
sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler);
- if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1)
- return NULL;
+ Py_INCREF(progress_handler);
+ Py_XSETREF(self->function_pinboard_progress_handler, progress_handler);
}
Py_RETURN_NONE;
if (trace_callback == Py_None) {
/* None clears the trace callback previously set */
sqlite3_trace(self->db, 0, (void*)0);
+ Py_XSETREF(self->function_pinboard_trace_callback, NULL);
} else {
- if (PyDict_SetItem(self->function_pinboard, trace_callback, Py_None) == -1)
- return NULL;
sqlite3_trace(self->db, _trace_callback, trace_callback);
+ Py_INCREF(trace_callback);
+ Py_XSETREF(self->function_pinboard_trace_callback, trace_callback);
}
Py_RETURN_NONE;
Py_RETURN_FALSE;
}
-static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level)
+static int
+pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored))
{
+ if (isolation_level == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+ return -1;
+ }
if (isolation_level == Py_None) {
PyObject *res = pysqlite_connection_commit(self, NULL);
if (!res) {
if (!_PyArg_NoKeywords(MODULE_NAME ".Connection", kwargs))
return NULL;
- if (!PyArg_ParseTuple(args, "O", &sql))
+ if (!PyArg_ParseTuple(args, "U", &sql))
return NULL;
_pysqlite_drop_unused_statement_references(self);
return retval;
}
-/* Function author: Paul Kippes <kippesp@gmail.com>
- * Class method of Connection to call the Python function _iterdump
- * of the sqlite3 module.
- */
-static PyObject *
-pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args)
-{
- PyObject* retval = NULL;
- PyObject* module = NULL;
- PyObject* module_dict;
- PyObject* pyfn_iterdump;
-
- if (!pysqlite_check_connection(self)) {
- goto finally;
- }
-
- module = PyImport_ImportModule(MODULE_NAME ".dump");
- if (!module) {
- goto finally;
- }
-
- module_dict = PyModule_GetDict(module);
- if (!module_dict) {
- goto finally;
- }
-
- pyfn_iterdump = PyDict_GetItemString(module_dict, "_iterdump");
- if (!pyfn_iterdump) {
- PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference");
- goto finally;
- }
-
- args = PyTuple_New(1);
- if (!args) {
- goto finally;
- }
- Py_INCREF(self);
- PyTuple_SetItem(args, 0, (PyObject*)self);
- retval = PyObject_CallObject(pyfn_iterdump, args);
-
-finally:
- Py_XDECREF(args);
- Py_XDECREF(module);
- return retval;
-}
-
#ifdef HAVE_BACKUP_API
static PyObject *
pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds)
return NULL;
}
+ // XXX: We use _PyTime_ROUND_CEILING to support 3.6.x, but it should
+ // use _PyTime_ROUND_TIMEOUT instead.
if (sleep_obj != NULL) {
_PyTime_t sleep_secs;
if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj,
PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc));
#else
switch (rc) {
+ case SQLITE_ERROR:
+ /* Description of SQLITE_ERROR in SQLite 3.7.14 and older
+ releases. */
+ PyErr_SetString(pysqlite_OperationalError,
+ "SQL logic error or missing database");
+ break;
case SQLITE_READONLY:
PyErr_SetString(pysqlite_OperationalError,
"attempt to write a readonly database");
};
static PyMethodDef connection_methods[] = {
- {"cursor", (PyCFunction)pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS,
+ {"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.")},
PyDoc_STR("Commit the current transaction.")},
{"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS,
PyDoc_STR("Roll back the current transaction.")},
- {"create_function", (PyCFunction)pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS,
+ {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Creates a new function. Non-standard.")},
- {"create_aggregate", (PyCFunction)pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS,
+ {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Creates a new aggregate. Non-standard.")},
#ifdef HAVE_WINDOW_FUNCTION
{"create_window_function", (PyCFunction)pysqlite_connection_create_window_function, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Creates a new window function. Non-standard.")},
#endif
- {"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
+ {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Sets authorizer callback. Non-standard.")},
#ifdef HAVE_LOAD_EXTENSION
{"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS,
{"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS,
PyDoc_STR("Load SQLite extension module. Non-standard.")},
#endif
- {"set_progress_handler", (PyCFunction)pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS,
+ {"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)pysqlite_connection_set_trace_callback, METH_VARARGS|METH_KEYWORDS,
+ {"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.")},
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.")},
#ifdef HAVE_BACKUP_API
- {"backup", (PyCFunction)pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS,
+ {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS,
PyDoc_STR("Makes a backup of the database. Non-standard.")},
#endif
{"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS,
#ifndef PYSQLITE_CONNECTION_H
#define PYSQLITE_CONNECTION_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pythread.h"
#include "structmember.h"
*/
PyObject* text_factory;
- /* remember references to functions/classes used in
- * create_function/create/aggregate, use these as dictionary keys, so we
- * can keep the total system refcount constant by clearing that dictionary
- * in connection_dealloc */
- PyObject* function_pinboard;
+ /* remember references to functions/classes used in trace/progress/auth cb */
+ PyObject* function_pinboard_trace_callback;
+ PyObject* function_pinboard_progress_handler;
+ PyObject* function_pinboard_authorizer_cb;
/* a dictionary of registered collation name => collation callable mappings */
PyObject* collations;
Py_XSETREF(self->connection, connection);
Py_CLEAR(self->statement);
Py_CLEAR(self->next_row);
-
- Py_XSETREF(self->row_cast_map, PyList_New(0));
- if (!self->row_cast_map) {
- return -1;
- }
+ Py_CLEAR(self->row_cast_map);
Py_INCREF(Py_None);
Py_XSETREF(self->description, Py_None);
Py_TYPE(self)->tp_free((PyObject*)self);
}
-PyObject* _pysqlite_get_converter(PyObject* key)
+static PyObject *
+_pysqlite_get_converter(const char *keystr, Py_ssize_t keylen)
{
- PyObject* upcase_key;
- PyObject* retval;
+ PyObject *key;
+ PyObject *upcase_key;
+ PyObject *retval;
_Py_IDENTIFIER(upper);
+ key = PyUnicode_FromStringAndSize(keystr, keylen);
+ if (!key) {
+ return NULL;
+ }
upcase_key = _PyObject_CallMethodId(key, &PyId_upper, NULL);
+ Py_DECREF(key);
if (!upcase_key) {
return NULL;
}
- retval = PyDict_GetItem(converters, upcase_key);
+ retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key);
Py_DECREF(upcase_key);
return retval;
}
-int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
+static int
+pysqlite_build_row_cast_map(pysqlite_Cursor* self)
{
int i;
- const char* type_start = (const char*)-1;
const char* pos;
-
const char* colname;
const char* decltype;
- PyObject* py_decltype;
PyObject* converter;
- PyObject* key;
if (!self->connection->detect_types) {
return 0;
}
Py_XSETREF(self->row_cast_map, PyList_New(0));
+ if (!self->row_cast_map) {
+ return -1;
+ }
for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
converter = NULL;
if (self->connection->detect_types & PARSE_COLNAMES) {
colname = sqlite3_column_name(self->statement->st, i);
if (colname) {
+ const char *type_start = NULL;
for (pos = colname; *pos != 0; pos++) {
if (*pos == '[') {
type_start = pos + 1;
- } else if (*pos == ']' && type_start != (const char*)-1) {
- key = PyUnicode_FromStringAndSize(type_start, pos - type_start);
- if (!key) {
- /* creating a string failed, but it is too complicated
- * to propagate the error here, we just assume there is
- * no converter and proceed */
- break;
+ }
+ else if (*pos == ']' && type_start != NULL) {
+ converter = _pysqlite_get_converter(type_start, pos - type_start);
+ if (!converter && PyErr_Occurred()) {
+ Py_CLEAR(self->row_cast_map);
+ return -1;
}
-
- converter = _pysqlite_get_converter(key);
- Py_DECREF(key);
break;
}
}
* 'NUMBER(10)' to be treated as 'NUMBER', for example.
* In other words, it will work as people expect it to work.*/
if (*pos == ' ' || *pos == '(' || *pos == 0) {
- py_decltype = PyUnicode_FromStringAndSize(decltype, pos - decltype);
- if (!py_decltype) {
+ converter = _pysqlite_get_converter(decltype, pos - decltype);
+ if (!converter && PyErr_Occurred()) {
+ Py_CLEAR(self->row_cast_map);
return -1;
}
break;
}
}
-
- converter = _pysqlite_get_converter(py_decltype);
- Py_DECREF(py_decltype);
}
}
}
if (PyList_Append(self->row_cast_map, converter) != 0) {
- if (converter != Py_None) {
- Py_DECREF(converter);
- }
Py_CLEAR(self->row_cast_map);
-
return -1;
}
}
return 0;
}
-PyObject* _pysqlite_build_column_name(const char* colname)
+static PyObject *
+_pysqlite_build_column_name(const char* colname)
{
const char* pos;
* Precondidition:
* - sqlite3_step() has been called before and it returned SQLITE_ROW.
*/
-PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
+static PyObject *
+_pysqlite_fetch_one_row(pysqlite_Cursor* self)
{
int i, numcols;
PyObject* row;
PyObject* converter;
PyObject* converted;
Py_ssize_t nbytes;
- PyObject* buffer;
const char* val_str;
char buf[200];
const char* colname;
- PyObject* buf_bytes;
- PyObject* error_obj;
+ PyObject* error_msg;
if (self->reset) {
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
return NULL;
for (i = 0; i < numcols; i++) {
- if (self->connection->detect_types) {
- converter = PyList_GetItem(self->row_cast_map, i);
- if (!converter) {
- converter = Py_None;
- }
- } else {
+ if (self->connection->detect_types
+ && self->row_cast_map != NULL
+ && i < PyList_GET_SIZE(self->row_cast_map))
+ {
+ converter = PyList_GET_ITEM(self->row_cast_map, i);
+ }
+ else {
converter = Py_None;
}
goto error;
converted = PyObject_CallFunction(converter, "O", item);
Py_DECREF(item);
- if (!converted)
- break;
}
} else {
Py_BEGIN_ALLOW_THREADS
nbytes = sqlite3_column_bytes(self->statement->st, i);
if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) {
converted = PyUnicode_FromStringAndSize(val_str, nbytes);
- if (!converted) {
+ if (!converted && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
PyErr_Clear();
colname = sqlite3_column_name(self->statement->st, i);
if (!colname) {
}
PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
colname , val_str);
- buf_bytes = PyByteArray_FromStringAndSize(buf, strlen(buf));
- if (!buf_bytes) {
+ error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace");
+ if (!error_msg) {
PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8");
} else {
- error_obj = PyUnicode_FromEncodedObject(buf_bytes, "ascii", "replace");
- if (!error_obj) {
- PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8");
- } else {
- PyErr_SetObject(pysqlite_OperationalError, error_obj);
- Py_DECREF(error_obj);
- }
- Py_DECREF(buf_bytes);
+ PyErr_SetObject(pysqlite_OperationalError, error_msg);
+ Py_DECREF(error_msg);
}
}
} else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) {
} else {
/* coltype == SQLITE_BLOB */
nbytes = sqlite3_column_bytes(self->statement->st, i);
- buffer = PyBytes_FromStringAndSize(
+ converted = PyBytes_FromStringAndSize(
sqlite3_column_blob(self->statement->st, i), nbytes);
- if (!buffer)
- break;
- converted = buffer;
}
}
- if (converted) {
- PyTuple_SetItem(row, i, converted);
- } else {
- Py_INCREF(Py_None);
- PyTuple_SetItem(row, i, Py_None);
+ if (!converted) {
+ goto error;
}
+ PyTuple_SetItem(row, i, converted);
}
if (PyErr_Occurred())
return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
}
-PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
+static PyObject *
+_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
{
PyObject* operation;
- const char* operation_cstr;
- Py_ssize_t operation_len;
PyObject* parameters_list = NULL;
PyObject* parameters_iter = NULL;
PyObject* parameters = NULL;
if (multiple) {
/* executemany() */
- if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
- goto error;
- }
-
- if (!PyUnicode_Check(operation)) {
- PyErr_SetString(PyExc_ValueError, "operation parameter must be str");
+ if (!PyArg_ParseTuple(args, "UO", &operation, &second_argument)) {
goto error;
}
}
} else {
/* execute() */
- if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
- goto error;
- }
-
- if (!PyUnicode_Check(operation)) {
- PyErr_SetString(PyExc_ValueError, "operation parameter must be str");
+ if (!PyArg_ParseTuple(args, "U|O", &operation, &second_argument)) {
goto error;
}
pysqlite_statement_reset(self->statement);
}
- operation_cstr = PyUnicode_AsUTF8AndSize(operation, &operation_len);
- if (operation_cstr == NULL)
- goto error;
-
/* reset description and rowcount */
Py_INCREF(Py_None);
Py_SETREF(self->description, Py_None);
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
if (PyErr_Occurred()) {
/* there was an error that occurred in a user-defined callback */
- if (_enable_callback_tracebacks) {
+ if (_pysqlite_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
}
if (pysqlite_build_row_cast_map(self) != 0) {
- PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
+ _PyErr_FormatFromCause(pysqlite_OperationalError, "Error while building row_cast_map");
goto error;
}
return _pysqlite_query_execute(self, 1, args);
}
-PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
+static PyObject *
+pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
{
PyObject* script_obj;
PyObject* script_str = NULL;
}
}
-PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self)
-{
- Py_INCREF(self);
- return (PyObject*)self;
-}
-
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
{
PyObject* next_row_tuple;
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)pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS,
+ {"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.")},
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */
- (getiterfunc)pysqlite_cursor_getiter, /* tp_iter */
+ PyObject_SelfIter, /* tp_iter */
(iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */
cursor_methods, /* tp_methods */
cursor_members, /* tp_members */
#ifndef PYSQLITE_CURSOR_H
#define PYSQLITE_CURSOR_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "statement.h"
PyObject *
pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
{
- PyObject *adapter, *key;
+ PyObject *adapter, *key, *adapted;
/* we don't check for exact type conformance as specified in PEP 246
because the pysqlite_PrepareProtocolType type is abstract and there is no
if (!key) {
return NULL;
}
- adapter = PyDict_GetItem(psyco_adapters, key);
+ adapter = PyDict_GetItemWithError(psyco_adapters, key);
Py_DECREF(key);
if (adapter) {
- PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ Py_INCREF(adapter);
+ adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
+ Py_DECREF(adapter);
return adapted;
}
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
/* try to have the protocol adapt this object*/
if (PyObject_HasAttrString(proto, "__adapt__")) {
_Py_IDENTIFIER(__adapt__);
- PyObject *adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj);
-
- if (adapted) {
- if (adapted != Py_None) {
- return adapted;
- } else {
- Py_DECREF(adapted);
- }
- }
+ adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj);
- if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
- return NULL;
+ if (adapted == Py_None) {
+ Py_DECREF(adapted);
+ }
+ else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) {
+ return adapted;
+ }
+ else {
+ PyErr_Clear();
+ }
}
/* and finally try to have the object adapt itself */
_Py_IDENTIFIER(__conform__);
PyObject *adapted = _PyObject_CallMethodId(obj, &PyId___conform__,"O", proto);
- if (adapted) {
- if (adapted != Py_None) {
- return adapted;
- } else {
- Py_DECREF(adapted);
- }
+ if (adapted == Py_None) {
+ Py_DECREF(adapted);
}
-
- if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
- return NULL;
+ else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) {
+ return adapted;
+ }
+ else {
+ PyErr_Clear();
}
}
+ if (alt) {
+ Py_INCREF(alt);
+ return alt;
+ }
+
/* else set the right exception and return NULL */
PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
return NULL;
#ifndef PSYCOPG_MICROPROTOCOLS_H
#define PSYCOPG_MICROPROTOCOLS_H 1
+#define PY_SSIZE_T_CLEAN
#include <Python.h>
/** the names of the three mandatory methods **/
PyObject *pysqlite_DataError = NULL;
PyObject *pysqlite_NotSupportedError = NULL;
-PyObject* converters = NULL;
-int _enable_callback_tracebacks = 0;
+PyObject* _pysqlite_converters = NULL;
+int _pysqlite_enable_callback_tracebacks = 0;
int pysqlite_BaseTypeAdapted = 0;
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
static char *kwlist[] = {
"database", "timeout", "detect_types", "isolation_level",
- "check_same_thread", "factory", "cached_statements", "uri", "flags",
- "vfs",
- NULL
+ "check_same_thread", "factory", "cached_statements", "uri",
+ "flags", "vfs", NULL
};
PyObject* database;
int detect_types = 0;
int check_same_thread = 1;
int cached_statements;
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
- char *vfs;
+ char *vfs = NULL;
int uri = 0;
double timeout = 5.0;
PyDoc_STRVAR(module_connect_doc,
"connect(database[, timeout, detect_types, isolation_level,\n\
- check_same_thread, factory, cached_statements, uri, flags])\n\
+ check_same_thread, factory, cached_statements, uri, flags, vfs])\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\
goto error;
}
- if (PyDict_SetItem(converters, name, callable) != 0) {
+ if (PyDict_SetItem(_pysqlite_converters, name, callable) != 0) {
goto error;
}
static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args)
{
- if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
+ if (!PyArg_ParseTuple(args, "i", &_pysqlite_enable_callback_tracebacks)) {
return NULL;
}
static void converters_init(PyObject* dict)
{
- converters = PyDict_New();
- if (!converters) {
+ _pysqlite_converters = PyDict_New();
+ if (!_pysqlite_converters) {
return;
}
- PyDict_SetItemString(dict, "converters", converters);
+ PyDict_SetItemString(dict, "converters", _pysqlite_converters);
}
static PyMethodDef module_methods[] = {
- {"connect", (PyCFunction)module_connect,
+ {"connect", (PyCFunction)(void(*)(void))module_connect,
METH_VARARGS | METH_KEYWORDS, module_connect_doc},
- {"complete_statement", (PyCFunction)module_complete,
+ {"complete_statement", (PyCFunction)(void(*)(void))module_complete,
METH_VARARGS | METH_KEYWORDS, module_complete_doc},
#ifdef HAVE_SHARED_CACHE
- {"enable_shared_cache", (PyCFunction)module_enable_shared_cache,
+ {"enable_shared_cache", (PyCFunction)(void(*)(void))module_enable_shared_cache,
METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc},
#endif
{"register_adapter", (PyCFunction)module_register_adapter,
#ifndef PYSQLITE_MODULE_H
#define PYSQLITE_MODULE_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#define PYSQLITE_VERSION "2.6.0"
extern PyObject* pysqlite_DataError;
extern PyObject* pysqlite_NotSupportedError;
-/* the functions time.time() and time.sleep() */
-extern PyObject* time_time;
-extern PyObject* time_sleep;
-
/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter
* functions, that convert the SQL value to the appropriate Python value.
* The key is uppercase.
*/
-extern PyObject* converters;
+extern PyObject* _pysqlite_converters;
-extern int _enable_callback_tracebacks;
+extern int _pysqlite_enable_callback_tracebacks;
extern int pysqlite_BaseTypeAdapted;
#define PARSE_DECLTYPES 1
#ifndef PYSQLITE_PREPARE_PROTOCOL_H
#define PYSQLITE_PREPARE_PROTOCOL_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
typedef struct
}
}
-Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
+static Py_ssize_t
+pysqlite_row_length(pysqlite_Row* self)
{
return PyTuple_GET_SIZE(self->data);
}
return list;
}
-static int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags)
-{
- return (&PyTuple_Type)->tp_print(self->data, fp, flags);
-}
-
static PyObject* pysqlite_iter(pysqlite_Row* self)
{
return PyObject_GetIter(self->data);
sizeof(pysqlite_Row), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)pysqlite_row_dealloc, /* tp_dealloc */
- (printfunc)pysqlite_row_print, /* tp_print */
+ 0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
#ifndef PYSQLITE_ROW_H
#define PYSQLITE_ROW_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
typedef struct _Row
self->st = NULL;
self->in_use = 0;
+ assert(PyUnicode_Check(sql));
+
sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len);
if (sql_cstr == NULL) {
rc = PYSQLITE_SQL_WRONG_TYPE;
Py_INCREF(sql);
self->sql = sql;
- /* Determine if the statement is a DML statement.
- SELECT is the only exception. See #9924. */
- self->is_dml = 0;
- for (p = sql_cstr; *p != 0; p++) {
- switch (*p) {
- case ' ':
- case '\r':
- case '\n':
- case '\t':
- continue;
- }
-
- self->is_dml = (PyOS_strnicmp(p, "insert ", 7) == 0)
- || (PyOS_strnicmp(p, "update ", 7) == 0)
- || (PyOS_strnicmp(p, "delete ", 7) == 0)
- || (PyOS_strnicmp(p, "replace ", 8) == 0);
- break;
- }
-
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_prepare_v2(connection->db,
sql_cstr,
-1,
&self->st,
&tail);
+ self->is_dml = !sqlite3_stmt_readonly(self->st);
Py_END_ALLOW_THREADS
+ /* To retain backward-compatibility, we need to treat DDL and certain types
+ * of transactions as being "not-dml".
+ */
+ if (self->is_dml) {
+ for (p = sql_cstr; *p != 0; p++) {
+ switch (*p) {
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ continue;
+ }
+
+ /* DML iff statement is not a CREATE/DROP/BEGIN. */
+ self->is_dml = (PyOS_strnicmp(p, "begin", 5) &&
+ PyOS_strnicmp(p, "create", 6) &&
+ PyOS_strnicmp(p, "drop", 4) &&
+ PyOS_strnicmp(p, "alter", 5) &&
+ PyOS_strnicmp(p, "analyze", 7) &&
+ PyOS_strnicmp(p, "reindex", 7) &&
+ PyOS_strnicmp(p, "vacuum", 6));
+ break;
+ }
+ }
+
self->db = connection->db;
if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) {
if (!_need_adapt(current_param)) {
adapted = current_param;
} else {
- adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL);
- if (adapted) {
- Py_DECREF(current_param);
- } else {
- PyErr_Clear();
- adapted = current_param;
+ adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param);
+ Py_DECREF(current_param);
+ if (!adapted) {
+ return;
}
}
} else if (PyDict_Check(parameters)) {
/* parameters passed as dictionary */
for (i = 1; i <= num_params_needed; i++) {
+ PyObject *binding_name_obj;
Py_BEGIN_ALLOW_THREADS
binding_name = sqlite3_bind_parameter_name(self->st, i);
Py_END_ALLOW_THREADS
}
binding_name++; /* skip first char (the colon) */
+ binding_name_obj = PyUnicode_FromString(binding_name);
+ if (!binding_name_obj) {
+ return;
+ }
if (PyDict_CheckExact(parameters)) {
- current_param = PyDict_GetItemString(parameters, binding_name);
+ current_param = PyDict_GetItemWithError(parameters, binding_name_obj);
Py_XINCREF(current_param);
} else {
- current_param = PyMapping_GetItemString(parameters, binding_name);
+ current_param = PyObject_GetItem(parameters, binding_name_obj);
}
+ Py_DECREF(binding_name_obj);
if (!current_param) {
- PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i);
+ if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) {
+ PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i);
+ }
return;
}
if (!_need_adapt(current_param)) {
adapted = current_param;
} else {
- adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL);
- if (adapted) {
- Py_DECREF(current_param);
- } else {
- PyErr_Clear();
- adapted = current_param;
+ adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param);
+ Py_DECREF(current_param);
+ if (!adapted) {
+ return;
}
}
#ifndef PYSQLITE_STATEMENT_H
#define PYSQLITE_STATEMENT_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "connection.h"
#ifndef PYSQLITE_UTIL_H
#define PYSQLITE_UTIL_H
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"