aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/_sqlite/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_sqlite/connection.c')
-rw-r--r--Modules/_sqlite/connection.c222
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 */