summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_sqlite/cursor.c')
-rw-r--r--Modules/_sqlite/cursor.c129
1 files changed, 54 insertions, 75 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index e1cd536..86fbd4e 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -1,6 +1,6 @@
/* cursor.c - the cursor type
*
- * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
+ * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
@@ -26,7 +26,7 @@
#include "util.h"
#include "sqlitecompat.h"
-/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
+/* used to decide wether to call PyLong_FromLong or PyLong_FromLongLong */
#ifndef INT32_MIN
#define INT32_MIN (-2147483647 - 1)
#endif
@@ -38,10 +38,10 @@ 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(char* statement)
+static pysqlite_StatementKind detect_statement_type(const char* statement)
{
char buf[20];
- char* src;
+ const char* src;
char* dst;
src = statement;
@@ -145,7 +145,7 @@ static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
PyObject_ClearWeakRefs((PyObject*)self);
}
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
PyObject* _pysqlite_get_converter(PyObject* key)
@@ -193,7 +193,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
if (*pos == '[') {
type_start = pos + 1;
} else if (*pos == ']' && type_start != (const char*)-1) {
- key = PyString_FromStringAndSize(type_start, pos - type_start);
+ 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
@@ -218,7 +218,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
* 'NUMBER(10)' to be treated as 'NUMBER', for example.
* In other words, it will work as people expect it to work.*/
if (*pos == ' ' || *pos == '(' || *pos == 0) {
- py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
+ py_decltype = PyUnicode_FromStringAndSize(decltype, pos - decltype);
if (!py_decltype) {
return -1;
}
@@ -263,36 +263,14 @@ PyObject* _pysqlite_build_column_name(const char* colname)
if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) {
pos--;
}
- return PyString_FromStringAndSize(colname, pos - colname);
+ return PyUnicode_FromStringAndSize(colname, pos - colname);
}
}
}
PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t size, int optimize)
{
- const char* check;
- Py_ssize_t pos;
- int is_ascii = 0;
-
- if (optimize) {
- is_ascii = 1;
-
- check = val_str;
- for (pos = 0; pos < size; pos++) {
- if (*check & 0x80) {
- is_ascii = 0;
- break;
- }
-
- check++;
- }
- }
-
- if (is_ascii) {
- return PyString_FromStringAndSize(val_str, size);
- } else {
- return PyUnicode_DecodeUTF8(val_str, size, NULL);
- }
+ return PyUnicode_FromStringAndSize(val_str, size);
}
/*
@@ -312,10 +290,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
PyObject* converted;
Py_ssize_t nbytes;
PyObject* buffer;
- void* raw_buffer;
const char* val_str;
char buf[200];
const char* colname;
+ PyObject* buf_bytes;
+ PyObject* error_obj;
if (self->reset) {
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
@@ -348,7 +327,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
Py_INCREF(Py_None);
converted = Py_None;
} else {
- item = PyString_FromStringAndSize(val_str, nbytes);
+ item = PyBytes_FromStringAndSize(val_str, nbytes);
if (!item) {
return NULL;
}
@@ -370,7 +349,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
if (intval < INT32_MIN || intval > INT32_MAX) {
converted = PyLong_FromLongLong(intval);
} else {
- converted = PyInt_FromLong((long)intval);
+ converted = PyLong_FromLong((long)intval);
}
} else if (coltype == SQLITE_FLOAT) {
converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
@@ -390,24 +369,35 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
}
PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
colname , val_str);
- PyErr_SetString(pysqlite_OperationalError, buf);
+ buf_bytes = PyByteArray_FromStringAndSize(buf, strlen(buf));
+ if (!buf_bytes) {
+ 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);
+ }
}
- } else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
- converted = PyString_FromStringAndSize(val_str, nbytes);
+ } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) {
+ converted = PyBytes_FromStringAndSize(val_str, nbytes);
+ } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) {
+ converted = PyByteArray_FromStringAndSize(val_str, nbytes);
} else {
- converted = PyObject_CallFunction(self->connection->text_factory, "s#", val_str, nbytes);
+ converted = PyObject_CallFunction(self->connection->text_factory, "y#", val_str, nbytes);
}
} else {
/* coltype == SQLITE_BLOB */
nbytes = sqlite3_column_bytes(self->statement->st, i);
- buffer = PyBuffer_New(nbytes);
+ buffer = PyBytes_FromStringAndSize(
+ sqlite3_column_blob(self->statement->st, i), nbytes);
if (!buffer) {
break;
}
- if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) {
- break;
- }
- memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes);
converted = buffer;
}
}
@@ -456,8 +446,8 @@ static int check_cursor(pysqlite_Cursor* cur)
PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
{
PyObject* operation;
- PyObject* operation_bytestr = NULL;
- char* operation_cstr;
+ const char* operation_cstr;
+ Py_ssize_t operation_len;
PyObject* parameters_list = NULL;
PyObject* parameters_iter = NULL;
PyObject* parameters = NULL;
@@ -492,8 +482,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
goto error;
}
- if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
- PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+ if (!PyUnicode_Check(operation)) {
+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str");
goto error;
}
@@ -514,8 +504,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
goto error;
}
- if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
- PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
+ if (!PyUnicode_Check(operation)) {
+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str");
goto error;
}
@@ -549,16 +539,9 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
rc = pysqlite_statement_reset(self->statement);
}
- if (PyString_Check(operation)) {
- operation_cstr = PyString_AsString(operation);
- } else {
- operation_bytestr = PyUnicode_AsUTF8String(operation);
- if (!operation_bytestr) {
- goto error;
- }
-
- operation_cstr = PyString_AsString(operation_bytestr);
- }
+ operation_cstr = _PyUnicode_AsStringAndSize(operation, &operation_len);
+ if (operation_cstr == NULL)
+ goto error;
/* reset description and rowcount */
Py_DECREF(self->description);
@@ -639,6 +622,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
}
}
+
while (1) {
parameters = PyIter_Next(parameters_iter);
if (!parameters) {
@@ -750,7 +734,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
Py_BEGIN_ALLOW_THREADS
lastrowid = sqlite3_last_insert_rowid(self->connection->db);
Py_END_ALLOW_THREADS
- self->lastrowid = PyInt_FromLong((long)lastrowid);
+ self->lastrowid = PyLong_FromLong((long)lastrowid);
} else {
Py_INCREF(Py_None);
self->lastrowid = Py_None;
@@ -772,7 +756,6 @@ error:
#endif
#endif
- Py_XDECREF(operation_bytestr);
Py_XDECREF(parameters);
Py_XDECREF(parameters_iter);
Py_XDECREF(parameters_list);
@@ -817,17 +800,13 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
self->reset = 0;
- if (PyString_Check(script_obj)) {
- script_cstr = PyString_AsString(script_obj);
- } else if (PyUnicode_Check(script_obj)) {
- script_str = PyUnicode_AsUTF8String(script_obj);
- if (!script_str) {
+ if (PyUnicode_Check(script_obj)) {
+ script_cstr = _PyUnicode_AsString(script_obj);
+ if (!script_cstr) {
return NULL;
}
-
- script_cstr = PyString_AsString(script_str);
} else {
- PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string.");
+ PyErr_SetString(PyExc_ValueError, "script argument must be unicode.");
return NULL;
}
@@ -1076,11 +1055,11 @@ static PyMethodDef cursor_methods[] = {
static struct PyMemberDef cursor_members[] =
{
- {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), RO},
- {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO},
+ {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY},
+ {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY},
{"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
- {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO},
- {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO},
+ {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY},
+ {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY},
{"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
{NULL}
};
@@ -1097,7 +1076,7 @@ PyTypeObject pysqlite_CursorType = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_compare */
+ 0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -1108,7 +1087,7 @@ PyTypeObject pysqlite_CursorType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
cursor_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */