diff options
Diffstat (limited to 'Modules/_sqlite')
| -rw-r--r-- | Modules/_sqlite/cache.c | 10 | ||||
| -rw-r--r-- | Modules/_sqlite/cache.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/connection.c | 222 | ||||
| -rw-r--r-- | Modules/_sqlite/connection.h | 11 | ||||
| -rw-r--r-- | Modules/_sqlite/cursor.c | 129 | ||||
| -rw-r--r-- | Modules/_sqlite/cursor.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/module.c | 53 | ||||
| -rw-r--r-- | Modules/_sqlite/module.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/prepare_protocol.c | 4 | ||||
| -rw-r--r-- | Modules/_sqlite/prepare_protocol.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/row.c | 21 | ||||
| -rw-r--r-- | Modules/_sqlite/row.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/sqlitecompat.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/statement.c | 90 | ||||
| -rw-r--r-- | Modules/_sqlite/statement.h | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/util.c | 2 | ||||
| -rw-r--r-- | Modules/_sqlite/util.h | 2 |
17 files changed, 223 insertions, 335 deletions
diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 0653367..735a242 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -1,6 +1,6 @@ /* cache .c - a LRU cache * - * 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. * @@ -242,12 +242,12 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) if (!fmt_args) { return NULL; } - template = PyString_FromString("%s <- %s ->%s\n"); + template = PyUnicode_FromString("%s <- %s ->%s\n"); if (!template) { Py_DECREF(fmt_args); return NULL; } - display_str = PyString_Format(template, fmt_args); + display_str = PyUnicode_Format(template, fmt_args); Py_DECREF(template); Py_DECREF(fmt_args); if (!display_str) { @@ -283,7 +283,7 @@ PyTypeObject pysqlite_NodeType = { 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 */ @@ -325,7 +325,7 @@ PyTypeObject pysqlite_CacheType = { 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 */ diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index b09517c..a133903 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -1,6 +1,6 @@ /* cache.h - definitions for the LRU cache * - * 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. * diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index a646513..9d4c72f 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1,9 +1,9 @@ /* connection.c - the connection 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. - * + * * 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. @@ -23,6 +23,7 @@ #include "cache.h" #include "module.h" +#include "structmember.h" #include "connection.h" #include "statement.h" #include "cursor.h" @@ -61,7 +62,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject { static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; - PyObject* database; + char* database; int detect_types = 0; PyObject* isolation_level = NULL; PyObject* factory = NULL; @@ -69,12 +70,8 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject int cached_statements = 100; double timeout = 5.0; int rc; - PyObject* class_attr = NULL; - PyObject* class_attr_str = NULL; - int is_apsw_connection = 0; - PyObject* database_utf8; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { return -1; @@ -94,57 +91,17 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject Py_INCREF(&PyUnicode_Type); self->text_factory = (PyObject*)&PyUnicode_Type; - if (PyString_Check(database) || PyUnicode_Check(database)) { - if (PyString_Check(database)) { - database_utf8 = database; - Py_INCREF(database_utf8); - } else { - database_utf8 = PyUnicode_AsUTF8String(database); - if (!database_utf8) { - return -1; - } - } - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_open(PyString_AsString(database_utf8), &self->db); - Py_END_ALLOW_THREADS - - Py_DECREF(database_utf8); - - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - return -1; - } - } else { - /* Create a pysqlite connection from a APSW connection */ - class_attr = PyObject_GetAttrString(database, "__class__"); - if (class_attr) { - class_attr_str = PyObject_Str(class_attr); - if (class_attr_str) { - if (strcmp(PyString_AsString(class_attr_str), "<type 'apsw.Connection'>") == 0) { - /* In the APSW Connection object, the first entry after - * PyObject_HEAD is the sqlite3* we want to get hold of. - * Luckily, this is the same layout as we have in our - * pysqlite_Connection */ - self->db = ((pysqlite_Connection*)database)->db; - - Py_INCREF(database); - self->apsw_connection = database; - is_apsw_connection = 1; - } - } - } - Py_XDECREF(class_attr_str); - Py_XDECREF(class_attr); + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_open(database, &self->db); + Py_END_ALLOW_THREADS - if (!is_apsw_connection) { - PyErr_SetString(PyExc_ValueError, "database parameter must be string or APSW Connection object"); - return -1; - } + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + return -1; } if (!isolation_level) { - isolation_level = PyString_FromString(""); + isolation_level = PyUnicode_FromString(""); if (!isolation_level) { return -1; } @@ -243,11 +200,13 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset weakref = PyList_GetItem(self->statements, i); statement = PyWeakref_GetObject(weakref); if (statement != Py_None) { + Py_INCREF(statement); if (action == ACTION_RESET) { (void)pysqlite_statement_reset((pysqlite_Statement*)statement); } else { (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); } + Py_DECREF(statement); } } @@ -264,8 +223,6 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset void pysqlite_connection_dealloc(pysqlite_Connection* self) { - PyObject* ret = NULL; - Py_XDECREF(self->statement_cache); /* Clean up if user has not called .close() explicitly. */ @@ -273,10 +230,6 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) Py_BEGIN_ALLOW_THREADS sqlite3_close(self->db); Py_END_ALLOW_THREADS - } else if (self->apsw_connection) { - ret = PyObject_CallMethod(self->apsw_connection, "close", ""); - Py_XDECREF(ret); - Py_XDECREF(self->apsw_connection); } if (self->begin_statement) { @@ -290,7 +243,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - self->ob_type->tp_free((PyObject*)self); + Py_TYPE(self)->tp_free((PyObject*)self); } /* @@ -353,7 +306,6 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) { - PyObject* ret; int rc; if (!pysqlite_check_thread(self)) { @@ -363,23 +315,15 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - if (self->apsw_connection) { - ret = PyObject_CallMethod(self->apsw_connection, "close", ""); - Py_XDECREF(ret); - Py_XDECREF(self->apsw_connection); - self->apsw_connection = NULL; - self->db = NULL; - } else { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_close(self->db); - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_close(self->db); + Py_END_ALLOW_THREADS - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - return NULL; - } else { - self->db = NULL; - } + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + return NULL; + } else { + self->db = NULL; } } @@ -542,32 +486,25 @@ void _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) { const char* buffer; Py_ssize_t buflen; - PyObject* stringval; if ((!py_val) || PyErr_Occurred()) { sqlite3_result_null(context); } else if (py_val == Py_None) { sqlite3_result_null(context); - } else if (PyInt_Check(py_val)) { - sqlite3_result_int64(context, (sqlite_int64)PyInt_AsLong(py_val)); } else if (PyLong_Check(py_val)) { sqlite3_result_int64(context, PyLong_AsLongLong(py_val)); } else if (PyFloat_Check(py_val)) { sqlite3_result_double(context, PyFloat_AsDouble(py_val)); - } else if (PyBuffer_Check(py_val)) { + } else if (PyUnicode_Check(py_val)) { + char *str = _PyUnicode_AsString(py_val); + if (str != NULL) + sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT); + } else if (PyObject_CheckBuffer(py_val)) { if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); } else { sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT); } - } else if (PyString_Check(py_val)) { - sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT); - } else if (PyUnicode_Check(py_val)) { - stringval = PyUnicode_AsUTF8String(py_val); - if (stringval) { - sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT); - Py_DECREF(stringval); - } } else { /* TODO: raise error */ } @@ -580,9 +517,7 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ sqlite3_value* cur_value; PyObject* cur_py_value; const char* val_str; - sqlite_int64 val_int; Py_ssize_t buflen; - void* raw_buffer; args = PyTuple_New(argc); if (!args) { @@ -593,18 +528,14 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ cur_value = argv[i]; switch (sqlite3_value_type(argv[i])) { case SQLITE_INTEGER: - val_int = sqlite3_value_int64(cur_value); - if(val_int < LONG_MIN || val_int > LONG_MAX) - cur_py_value = PyLong_FromLongLong(val_int); - else - cur_py_value = PyInt_FromLong((long)val_int); + cur_py_value = PyLong_FromLongLong(sqlite3_value_int64(cur_value)); break; case SQLITE_FLOAT: cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); break; case SQLITE_TEXT: val_str = (const char*)sqlite3_value_text(cur_value); - cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL); + cur_py_value = PyUnicode_FromString(val_str); /* TODO: have a way to show errors here */ if (!cur_py_value) { PyErr_Clear(); @@ -614,16 +545,8 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ break; case SQLITE_BLOB: buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyBuffer_New(buflen); - if (!cur_py_value) { - break; - } - if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) { - Py_DECREF(cur_py_value); - cur_py_value = NULL; - break; - } - memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen); + cur_py_value = PyBytes_FromStringAndSize( + sqlite3_value_blob(cur_value), buflen); break; case SQLITE_NULL: default: @@ -748,6 +671,7 @@ void _pysqlite_final_callback(sqlite3_context* context) { PyObject* function_result = NULL; PyObject** aggregate_instance; + PyObject* aggregate_class; #ifdef WITH_THREAD PyGILState_STATE threadstate; @@ -755,6 +679,8 @@ void _pysqlite_final_callback(sqlite3_context* context) threadstate = PyGILState_Ensure(); #endif + aggregate_class = (PyObject*)sqlite3_user_data(context); + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (!*aggregate_instance) { /* this branch is executed if there was an exception in the aggregate's @@ -934,8 +860,8 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co rc = SQLITE_DENY; } else { - if (PyInt_Check(ret)) { - rc = (int)PyInt_AsLong(ret); + if (PyLong_Check(ret)) { + rc = (int)PyLong_AsLong(ret); } else { rc = SQLITE_DENY; } @@ -967,7 +893,7 @@ static int _progress_handler(void* user_arg) } /* abort query if error occurred */ - rc = 1; + rc = 1; } else { rc = (int)PyObject_IsTrue(ret); Py_DECREF(ret); @@ -1124,7 +1050,7 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py { PyObject* res; PyObject* begin_statement; - char* begin_statement_str; + static PyObject* begin_word; Py_XDECREF(self->isolation_level); @@ -1145,30 +1071,33 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py self->inTransaction = 0; } else { + const char *statement; + Py_ssize_t size; + Py_INCREF(isolation_level); self->isolation_level = isolation_level; - begin_statement = PyString_FromString("BEGIN "); - if (!begin_statement) { - return -1; + if (!begin_word) { + begin_word = PyUnicode_FromString("BEGIN "); + if (!begin_word) return -1; } - PyString_Concat(&begin_statement, isolation_level); + begin_statement = PyUnicode_Concat(begin_word, isolation_level); if (!begin_statement) { return -1; } - begin_statement_str = PyString_AsString(begin_statement); - if (!begin_statement_str) { + statement = _PyUnicode_AsStringAndSize(begin_statement, &size); + if (!statement) { Py_DECREF(begin_statement); return -1; } - self->begin_statement = PyMem_Malloc(strlen(begin_statement_str) + 2); + self->begin_statement = PyMem_Malloc(size + 2); if (!self->begin_statement) { Py_DECREF(begin_statement); return -1; } - strcpy(self->begin_statement, begin_statement_str); + strcpy(self->begin_statement, statement); Py_DECREF(begin_statement); } @@ -1346,8 +1275,8 @@ pysqlite_collation_callback( goto finally; } - string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length); - string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length); + string1 = PyUnicode_FromStringAndSize((const char*)text1_data, text1_length); + string2 = PyUnicode_FromStringAndSize((const char*)text2_data, text2_length); if (!string1 || !string2) { goto finally; /* failed to allocate strings */ @@ -1360,7 +1289,7 @@ pysqlite_collation_callback( goto finally; } - result = PyInt_AsLong(retval); + result = PyLong_AsLong(retval); if (PyErr_Occurred()) { result = 0; } @@ -1446,14 +1375,16 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) PyObject* uppercase_name = 0; PyObject* name; PyObject* retval; - char* chk; + Py_UNICODE* chk; + Py_ssize_t i, len; + char *uppercase_name_str; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { goto finally; } - if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) { + if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyUnicode_Type, &name, &callable)) { goto finally; } @@ -1462,19 +1393,24 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - chk = PyString_AsString(uppercase_name); - while (*chk) { + len = PyUnicode_GET_SIZE(uppercase_name); + chk = PyUnicode_AS_UNICODE(uppercase_name); + for (i=0; i<len; i++, chk++) { if ((*chk >= '0' && *chk <= '9') || (*chk >= 'A' && *chk <= 'Z') || (*chk == '_')) { - chk++; + continue; } else { PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name"); goto finally; } } + uppercase_name_str = _PyUnicode_AsString(uppercase_name); + if (!uppercase_name_str) + goto finally; + if (callable != Py_None && !PyCallable_Check(callable)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); goto finally; @@ -1489,7 +1425,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) } rc = sqlite3_create_collation(self->db, - PyString_AsString(uppercase_name), + uppercase_name_str, SQLITE_UTF8, (callable != Py_None) ? callable : NULL, (callable != Py_None) ? pysqlite_collation_callback : NULL); @@ -1546,8 +1482,7 @@ pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) } Py_DECREF(result); - Py_INCREF(Py_False); - return Py_False; + Py_RETURN_FALSE; } static char connection_doc[] = @@ -1603,18 +1538,19 @@ static PyMethodDef connection_methods[] = { static struct PyMemberDef connection_members[] = { - {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), RO}, - {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), RO}, - {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), RO}, - {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), RO}, - {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), RO}, - {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), RO}, - {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), RO}, - {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), RO}, - {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), RO}, - {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), RO}, + {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), READONLY}, + {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), READONLY}, + {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), READONLY}, + {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), READONLY}, + {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), READONLY}, + {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), READONLY}, + {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), READONLY}, + {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), READONLY}, + {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), READONLY}, + {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY}, {NULL} }; @@ -1627,7 +1563,7 @@ PyTypeObject pysqlite_ConnectionType = { 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 */ diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index ecc8d2b..c8e2f7c 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -1,6 +1,6 @@ /* connection.h - definitions for the connection 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. * @@ -39,7 +39,7 @@ typedef struct /* 1 if we are currently within a transaction, i. e. if a BEGIN has been * issued */ - int inTransaction; + char inTransaction; /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a * bitwise combination thereof makes sense */ @@ -84,7 +84,7 @@ typedef struct /* Determines how bytestrings from SQLite are converted to Python objects: * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created. - * - PyString_Type: PyStrings are created as-is. + * - PyBytes_Type: PyStrings are created as-is. * - Any custom callable: Any object returned from the callable called with the bytestring * as single parameter. */ @@ -99,11 +99,6 @@ typedef struct /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; - /* if our connection was created from a APSW connection, we keep a - * reference to the APSW connection around and get rid of it in our - * destructor */ - PyObject* apsw_connection; - /* Exception objects */ PyObject* Warning; PyObject* Error; 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 */ diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index cf5389c..118ba38 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -1,6 +1,6 @@ /* cursor.h - definitions for 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. * diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 33611d9..cbc3b8e 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -1,6 +1,6 @@ /* module.c - the module itself * - * 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. * @@ -51,7 +51,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* * 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}; - PyObject* database; + char* database; int detect_types = 0; PyObject* isolation_level; PyObject* factory = NULL; @@ -61,10 +61,10 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* PyObject* result; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { - return NULL; + return NULL; } if (factory == NULL) { @@ -93,7 +93,7 @@ static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) { - return NULL; + return NULL; } if (sqlite3_complete(statement)) { @@ -122,7 +122,7 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) { - return NULL; + return NULL; } rc = sqlite3_enable_shared_cache(do_enable); @@ -155,8 +155,8 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) /* a basic type is adapted; there's a performance optimization if that's not the case * (99 % of all usages) */ - if (type == &PyInt_Type || type == &PyLong_Type || type == &PyFloat_Type - || type == &PyString_Type || type == &PyUnicode_Type || type == &PyBuffer_Type) { + if (type == &PyLong_Type || type == &PyFloat_Type + || type == &PyUnicode_Type || type == &PyByteArray_Type) { pysqlite_BaseTypeAdapted = 1; } @@ -180,7 +180,7 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) PyObject* callable; PyObject* retval = NULL; - if (!PyArg_ParseTuple(args, "SO", &orig_name, &callable)) { + if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { return NULL; } @@ -300,13 +300,26 @@ static IntConstantPair _int_constants[] = { {(char*)NULL, 0} }; -PyMODINIT_FUNC init_sqlite3(void) + +static struct PyModuleDef _sqlite3module = { + PyModuleDef_HEAD_INIT, + "_sqlite3", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__sqlite3(void) { PyObject *module, *dict; PyObject *tmp_obj; int i; - module = Py_InitModule("_sqlite3", module_methods); + module = PyModule_Create(&_sqlite3module); if (!module || (pysqlite_row_setup_types() < 0) || @@ -316,7 +329,8 @@ PyMODINIT_FUNC init_sqlite3(void) (pysqlite_statement_setup_types() < 0) || (pysqlite_prepare_protocol_setup_types() < 0) ) { - return; + Py_XDECREF(module); + return NULL; } Py_INCREF(&pysqlite_ConnectionType); @@ -338,12 +352,12 @@ PyMODINIT_FUNC init_sqlite3(void) /*** Create DB-API Exception hierarchy */ - if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) { + if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { goto error; } PyDict_SetItemString(dict, "Error", pysqlite_Error); - if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) { + if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { goto error; } PyDict_SetItemString(dict, "Warning", pysqlite_Warning); @@ -402,7 +416,7 @@ PyMODINIT_FUNC init_sqlite3(void) /* Set integer constants */ for (i = 0; _int_constants[i].constant_name != 0; i++) { - tmp_obj = PyInt_FromLong(_int_constants[i].constant_value); + tmp_obj = PyLong_FromLong(_int_constants[i].constant_value); if (!tmp_obj) { goto error; } @@ -410,13 +424,13 @@ PyMODINIT_FUNC init_sqlite3(void) Py_DECREF(tmp_obj); } - if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) { + if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { goto error; } PyDict_SetItemString(dict, "version", tmp_obj); Py_DECREF(tmp_obj); - if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) { + if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { goto error; } PyDict_SetItemString(dict, "sqlite_version", tmp_obj); @@ -434,7 +448,7 @@ PyMODINIT_FUNC init_sqlite3(void) /* Original comment from _bsddb.c in the Python core. This is also still * needed nowadays for Python 2.3/2.4. - * + * * PyEval_InitThreads is called here due to a quirk in python 1.5 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>: * The global interpreter lock is not initialized until the first @@ -453,5 +467,8 @@ error: if (PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed"); + Py_DECREF(module); + module = NULL; } + return module; } diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 8d17d61..0eddb67 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -1,6 +1,6 @@ /* module.h - definitions for the module * - * 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. * diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 9ed25e1..fc68874 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -1,6 +1,6 @@ /* prepare_protocol.c - the protocol for preparing values for SQLite * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * @@ -43,7 +43,7 @@ PyTypeObject pysqlite_PrepareProtocolType= { 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 */ diff --git a/Modules/_sqlite/prepare_protocol.h b/Modules/_sqlite/prepare_protocol.h index 1cdf708..924e162 100644 --- a/Modules/_sqlite/prepare_protocol.h +++ b/Modules/_sqlite/prepare_protocol.h @@ -1,6 +1,6 @@ /* prepare_protocol.h - the protocol for preparing values for SQLite * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 480b482..3d44094 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -1,6 +1,6 @@ /* row.c - an enhanced tuple for database rows * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * @@ -76,23 +76,20 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) PyObject* item; - if (PyInt_Check(idx)) { - _idx = PyInt_AsLong(idx); - item = PyTuple_GetItem(self->data, _idx); - Py_XINCREF(item); - return item; - } else if (PyLong_Check(idx)) { + if (PyLong_Check(idx)) { _idx = PyLong_AsLong(idx); item = PyTuple_GetItem(self->data, _idx); Py_XINCREF(item); return item; - } else if (PyString_Check(idx)) { - key = PyString_AsString(idx); + } else if (PyUnicode_Check(idx)) { + key = _PyUnicode_AsString(idx); + if (key == NULL) + return NULL; nitems = PyTuple_Size(self->description); for (i = 0; i < nitems; i++) { - compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)); + compare_key = _PyUnicode_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)); if (!compare_key) { return NULL; } @@ -169,7 +166,7 @@ static PyObject* pysqlite_iter(pysqlite_Row* self) return PyObject_GetIter(self->data); } -static long pysqlite_row_hash(pysqlite_Row *self) +static Py_hash_t pysqlite_row_hash(pysqlite_Row *self) { return PyObject_Hash(self->description) ^ PyObject_Hash(self->data); } @@ -215,7 +212,7 @@ PyTypeObject pysqlite_RowType = { (printfunc)pysqlite_row_print, /* 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 */ diff --git a/Modules/_sqlite/row.h b/Modules/_sqlite/row.h index dd9b0c3..d014109 100644 --- a/Modules/_sqlite/row.h +++ b/Modules/_sqlite/row.h @@ -1,6 +1,6 @@ /* row.h - an enhanced tuple for database rows * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/sqlitecompat.h b/Modules/_sqlite/sqlitecompat.h index 3408fc2..cf20f16 100644 --- a/Modules/_sqlite/sqlitecompat.h +++ b/Modules/_sqlite/sqlitecompat.h @@ -1,6 +1,6 @@ /* sqlitecompat.h - compatibility macros * - * Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index c777211..80bcc38 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -1,6 +1,6 @@ /* statement.c - the statement type * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * @@ -41,10 +41,8 @@ typedef enum { } parse_remaining_sql_state; typedef enum { - TYPE_INT, TYPE_LONG, TYPE_FLOAT, - TYPE_STRING, TYPE_UNICODE, TYPE_BUFFER, TYPE_UNKNOWN @@ -54,30 +52,21 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con { const char* tail; int rc; - PyObject* sql_str; - char* sql_cstr; + const char* sql_cstr; + Py_ssize_t sql_cstr_len; self->st = NULL; self->in_use = 0; - if (PyString_Check(sql)) { - sql_str = sql; - Py_INCREF(sql_str); - } else if (PyUnicode_Check(sql)) { - sql_str = PyUnicode_AsUTF8String(sql); - if (!sql_str) { - rc = PYSQLITE_SQL_WRONG_TYPE; - return rc; - } - } else { + sql_cstr = _PyUnicode_AsStringAndSize(sql, &sql_cstr_len); + if (sql_cstr == NULL) { rc = PYSQLITE_SQL_WRONG_TYPE; return rc; } self->in_weakreflist = NULL; - self->sql = sql_str; - - sql_cstr = PyString_AsString(sql_str); + Py_INCREF(sql); + self->sql = sql; Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(connection->db, @@ -101,79 +90,50 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars) { int rc = SQLITE_OK; - long longval; PY_LONG_LONG longlongval; const char* buffer; char* string; Py_ssize_t buflen; - PyObject* stringval; parameter_type paramtype; - char* c; if (parameter == Py_None) { rc = sqlite3_bind_null(self->st, pos); goto final; } - if (PyInt_CheckExact(parameter)) { - paramtype = TYPE_INT; - } else if (PyLong_CheckExact(parameter)) { + if (PyLong_CheckExact(parameter)) { paramtype = TYPE_LONG; } else if (PyFloat_CheckExact(parameter)) { paramtype = TYPE_FLOAT; - } else if (PyString_CheckExact(parameter)) { - paramtype = TYPE_STRING; } else if (PyUnicode_CheckExact(parameter)) { paramtype = TYPE_UNICODE; - } else if (PyBuffer_Check(parameter)) { - paramtype = TYPE_BUFFER; - } else if (PyInt_Check(parameter)) { - paramtype = TYPE_INT; } else if (PyLong_Check(parameter)) { paramtype = TYPE_LONG; } else if (PyFloat_Check(parameter)) { paramtype = TYPE_FLOAT; - } else if (PyString_Check(parameter)) { - paramtype = TYPE_STRING; } else if (PyUnicode_Check(parameter)) { paramtype = TYPE_UNICODE; + } else if (PyObject_CheckBuffer(parameter)) { + paramtype = TYPE_BUFFER; } else { paramtype = TYPE_UNKNOWN; } - if (paramtype == TYPE_STRING && !allow_8bit_chars) { - string = PyString_AS_STRING(parameter); - for (c = string; *c != 0; c++) { - if (*c & 0x80) { - PyErr_SetString(pysqlite_ProgrammingError, "You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings."); - rc = -1; - goto final; - } - } - } - switch (paramtype) { - case TYPE_INT: - longval = PyInt_AsLong(parameter); - rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval); - break; case TYPE_LONG: + /* in the overflow error case, longval/longlongval is -1, and an exception is set */ longlongval = PyLong_AsLongLong(parameter); - /* in the overflow error case, longlongval is -1, and an exception is set */ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval); break; case TYPE_FLOAT: rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); break; - case TYPE_STRING: - PyString_AsStringAndSize(parameter, &string, &buflen); - rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); - break; case TYPE_UNICODE: - stringval = PyUnicode_AsUTF8String(parameter); - PyString_AsStringAndSize(stringval, &string, &buflen); - rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); - Py_DECREF(stringval); + string = _PyUnicode_AsStringAndSize(parameter, &buflen); + if (string != NULL) + rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); + else + rc = -1; break; case TYPE_BUFFER: if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) { @@ -198,9 +158,8 @@ static int _need_adapt(PyObject* obj) return 1; } - if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj) - || PyFloat_CheckExact(obj) || PyString_CheckExact(obj) - || PyUnicode_CheckExact(obj) || PyBuffer_Check(obj)) { + if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) + || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) { return 0; } else { return 1; @@ -325,10 +284,15 @@ int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params) { const char* tail; int rc; - char* sql_cstr; + const char* sql_cstr; + Py_ssize_t sql_len; sqlite3_stmt* new_st; - sql_cstr = PyString_AsString(self->sql); + sql_cstr = _PyUnicode_AsStringAndSize(self->sql, &sql_len); + if (sql_cstr == NULL) { + rc = PYSQLITE_SQL_WRONG_TYPE; + return rc; + } Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->db, @@ -503,7 +467,7 @@ PyTypeObject pysqlite_StatementType = { 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 */ @@ -514,7 +478,7 @@ PyTypeObject pysqlite_StatementType = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 05fd5ff..e5da42e 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -1,6 +1,6 @@ /* statement.h - definitions for the statement type * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 6b57b76..b7faae8 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -1,6 +1,6 @@ /* util.c - various utility functions * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index 4269003..baf405c 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -1,6 +1,6 @@ /* util.h - various utility functions * - * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> + * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de> * * This file is part of pysqlite. * |
