Merged new pysqlite version 2.6.0 from trunk.

This commit is contained in:
Gerhard Häring 2010-03-05 15:20:03 +00:00
parent 06dbff3b1f
commit f9cee22446
24 changed files with 601 additions and 128 deletions

View file

@ -1,6 +1,6 @@
/* cursor.c - the cursor type
*
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
@ -36,6 +36,8 @@
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
static pysqlite_StatementKind detect_statement_type(const char* statement)
{
char buf[20];
@ -74,7 +76,7 @@ static pysqlite_StatementKind detect_statement_type(const char* statement)
}
}
int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
{
pysqlite_Connection* connection;
@ -87,6 +89,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
self->connection = connection;
self->statement = NULL;
self->next_row = NULL;
self->in_weakreflist = NULL;
self->row_cast_map = PyList_New(0);
if (!self->row_cast_map) {
@ -100,6 +103,8 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
self->lastrowid= Py_None;
self->arraysize = 1;
self->closed = 0;
self->reset = 0;
self->rowcount = -1L;
@ -110,10 +115,16 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
return -1;
}
if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) {
return -1;
}
self->initialized = 1;
return 0;
}
void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
{
int rc;
@ -130,6 +141,10 @@ void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
Py_XDECREF(self->row_factory);
Py_XDECREF(self->next_row);
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*)self);
}
Py_TYPE(self)->tp_free((PyObject*)self);
}
@ -281,6 +296,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
PyObject* buf_bytes;
PyObject* error_obj;
if (self->reset) {
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
return NULL;
}
Py_BEGIN_ALLOW_THREADS
numcols = sqlite3_data_count(self->statement->st);
Py_END_ALLOW_THREADS
@ -397,6 +417,26 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
return row;
}
/*
* Checks if a cursor object is usable.
*
* 0 => error; 1 => ok
*/
static int check_cursor(pysqlite_Cursor* cur)
{
if (!cur->initialized) {
PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called.");
return 0;
}
if (cur->closed) {
PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor.");
return 0;
} else {
return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
}
}
PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
{
PyObject* operation;
@ -416,13 +456,15 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
PyObject* second_argument = NULL;
int allow_8bit_chars;
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
if (!check_cursor(self)) {
return NULL;
}
self->reset = 0;
/* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
(self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode));
(self->connection->text_factory != pysqlite_OptimizedUnicode));
Py_XDECREF(self->next_row);
self->next_row = NULL;
@ -573,42 +615,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
}
}
func_args = PyTuple_New(1);
if (!func_args) {
goto error;
}
Py_INCREF(operation);
if (PyTuple_SetItem(func_args, 0, operation) != 0) {
goto error;
}
if (self->statement) {
(void)pysqlite_statement_reset(self->statement);
Py_DECREF(self->statement);
}
self->statement = (pysqlite_Statement*)pysqlite_cache_get(self->connection->statement_cache, func_args);
Py_DECREF(func_args);
if (!self->statement) {
goto error;
}
if (self->statement->in_use) {
Py_DECREF(self->statement);
self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType);
if (!self->statement) {
goto error;
}
rc = pysqlite_statement_create(self->statement, self->connection, operation);
if (rc != SQLITE_OK) {
Py_CLEAR(self->statement);
goto error;
}
}
pysqlite_statement_reset(self->statement);
pysqlite_statement_mark_dirty(self->statement);
while (1) {
parameters = PyIter_Next(parameters_iter);
@ -623,11 +629,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
goto error;
}
if (pysqlite_build_row_cast_map(self) != 0) {
PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
goto error;
}
/* Keep trying the SQL statement until the schema stops changing. */
while (1) {
/* Actually execute the SQL statement. */
@ -671,10 +672,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
}
if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
Py_BEGIN_ALLOW_THREADS
numcols = sqlite3_column_count(self->statement->st);
Py_END_ALLOW_THREADS
if (self->description == Py_None) {
Py_BEGIN_ALLOW_THREADS
numcols = sqlite3_column_count(self->statement->st);
@ -782,16 +779,17 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
sqlite3_stmt* statement;
int rc;
PyObject* result;
int statement_completed = 0;
if (!PyArg_ParseTuple(args, "O", &script_obj)) {
return NULL;
}
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
if (!check_cursor(self)) {
return NULL;
}
self->reset = 0;
if (PyUnicode_Check(script_obj)) {
script_cstr = _PyUnicode_AsString(script_obj);
if (!script_cstr) {
@ -810,11 +808,6 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
Py_DECREF(result);
while (1) {
if (!sqlite3_complete(script_cstr)) {
break;
}
statement_completed = 1;
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_prepare(self->connection->db,
script_cstr,
@ -845,15 +838,15 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
_pysqlite_seterror(self->connection->db, NULL);
goto error;
}
if (*script_cstr == (char)0) {
break;
}
}
error:
Py_XDECREF(script_str);
if (!statement_completed) {
PyErr_SetString(pysqlite_ProgrammingError, "you did not provide a complete SQL statement");
}
if (PyErr_Occurred()) {
return NULL;
} else {
@ -874,7 +867,12 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
PyObject* next_row;
int rc;
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
if (!check_cursor(self)) {
return NULL;
}
if (self->reset) {
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
return NULL;
}
@ -1017,6 +1015,8 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args)
Py_CLEAR(self->statement);
}
self->closed = 1;
Py_INCREF(Py_None);
return Py_None;
}
@ -1077,12 +1077,12 @@ PyTypeObject pysqlite_CursorType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
cursor_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */
(getiterfunc)pysqlite_cursor_getiter, /* tp_iter */
(iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */
cursor_methods, /* tp_methods */