diff options
Diffstat (limited to 'Modules/_sqlite/connection.c')
-rw-r--r-- | Modules/_sqlite/connection.c | 222 |
1 files changed, 79 insertions, 143 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index a646513c4a1..9d4c72f695b 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 */ |