Imported Upstream version 0.1.3 upstream/0.1.3
authorHyunjee Kim <hj0426.kim@samsung.com>
Fri, 10 Apr 2020 05:16:40 +0000 (14:16 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Fri, 10 Apr 2020 05:16:46 +0000 (14:16 +0900)
Change-Id: I82eea20df527fdff932bea7a5896ab3dea96bc03
Signed-off-by: Hyunjee Kim <hj0426.kim@samsung.com>
14 files changed:
PKG-INFO
lib/dbapi2.py
pysqlite3.egg-info/PKG-INFO
setup.py
src/connection.c
src/connection.h
src/cursor.c
src/microprotocols.c
src/microprotocols.h
src/module.c
src/row.c
src/statement.c
src/util.c
src/util.h

index bd795a63ac7fe8e46b6be7d9f81b8a0d0e037dab..d2063fdda94ec1815438c2ed0e31495eb4b17ad4 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pysqlite3
-Version: 0.1.2
+Version: 0.1.3
 Summary: DB-API 2.0 interface for Sqlite 3.x
 Home-page: https://github.com/rigglemania/pysqlcipher3
 Author: Charles Leifer
index 38e7b41291fa0c60e71d597d1c124a790bad8218..80dd4f99f0fb969ddcc5951b0c6874ddbf062d09 100644 (file)
@@ -24,7 +24,7 @@ import datetime
 import time
 import collections.abc
 
-from pysqlite3._sqlite import *
+from pysqlite3._sqlite3 import *
 
 paramstyle = "qmark"
 
index bd795a63ac7fe8e46b6be7d9f81b8a0d0e037dab..d2063fdda94ec1815438c2ed0e31495eb4b17ad4 100644 (file)
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pysqlite3
-Version: 0.1.2
+Version: 0.1.3
 Summary: DB-API 2.0 interface for Sqlite 3.x
 Home-page: https://github.com/rigglemania/pysqlcipher3
 Author: Charles Leifer
index 3519be2deb7eafabb9b87a57ae95502c38209777..8864b9039a851bd19f93a9dc74fa5bd49fcf73f6 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ from setuptools import Extension
 # If you need to change anything, it should be enough to change setup.cfg.
 
 PACKAGE_NAME = 'pysqlite3'
-VERSION = '0.1.2'
+VERSION = '0.1.3'
 
 # define sqlite sources
 sources = [os.path.join('src', source)
@@ -22,7 +22,7 @@ sources = [os.path.join('src', source)
 
 # define packages
 packages = [PACKAGE_NAME]
-EXTENSION_MODULE_NAME = "._sqlite"
+EXTENSION_MODULE_NAME = "._sqlite3"
 
 # Work around clang raising hard error for unused arguments
 if sys.platform == "darwin":
index 4ce58d988097d3a7d02b653cf01fe862b8cadab5..3b08b2bd431a8b2288ead51e5205d9be4c04be1e 100644 (file)
 #endif
 #endif
 
+#if SQLITE_VERSION_NUMBER >= 3006011
+#define HAVE_BACKUP_API
+#endif
+
 _Py_IDENTIFIER(cursor);
 
 static const char * const begin_statements[] = {
@@ -76,6 +80,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
     };
 
     char* database;
+    PyObject* database_obj;
     int detect_types = 0;
     PyObject* isolation_level = NULL;
     PyObject* factory = NULL;
@@ -86,8 +91,8 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
     double timeout = 5.0;
     int rc;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOipi", kwlist,
-                                     &database, &timeout, &detect_types,
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|diOiOipi", kwlist,
+                                     PyUnicode_FSConverter, &database_obj, &timeout, &detect_types,
                                      &isolation_level, &check_same_thread,
                                      &factory, &cached_statements, &uri,
                                      &flags))
@@ -95,19 +100,21 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
         return -1;
     }
 
+    database = PyBytes_AsString(database_obj);
+
     self->initialized = 1;
 
     self->begin_statement = NULL;
 
-    self->statement_cache = NULL;
-    self->statements = NULL;
-    self->cursors = NULL;
+    Py_CLEAR(self->statement_cache);
+    Py_CLEAR(self->statements);
+    Py_CLEAR(self->cursors);
 
     Py_INCREF(Py_None);
-    self->row_factory = Py_None;
+    Py_XSETREF(self->row_factory, Py_None);
 
     Py_INCREF(&PyUnicode_Type);
-    self->text_factory = (PyObject*)&PyUnicode_Type;
+    Py_XSETREF(self->text_factory, (PyObject*)&PyUnicode_Type);
 
 #ifdef SQLITE_OPEN_URI
     Py_BEGIN_ALLOW_THREADS
@@ -123,6 +130,8 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
 #endif
     Py_END_ALLOW_THREADS
 
+    Py_DECREF(database_obj);
+
     if (rc != SQLITE_OK) {
         _pysqlite_seterror(self->db, NULL);
         return -1;
@@ -136,7 +145,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
     } else {
         Py_INCREF(isolation_level);
     }
-    self->isolation_level = NULL;
+    Py_CLEAR(self->isolation_level);
     if (pysqlite_connection_set_isolation_level(self, isolation_level) < 0) {
         Py_DECREF(isolation_level);
         return -1;
@@ -169,21 +178,19 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
     self->detect_types = detect_types;
     self->timeout = timeout;
     (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
-#ifdef WITH_THREAD
     self->thread_ident = PyThread_get_thread_ident();
-#endif
     if (!check_same_thread && sqlite3_libversion_number() < 3003001) {
         PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available");
         return -1;
     }
     self->check_same_thread = check_same_thread;
 
-    self->function_pinboard = PyDict_New();
+    Py_XSETREF(self->function_pinboard, PyDict_New());
     if (!self->function_pinboard) {
         return -1;
     }
 
-    self->collations = PyDict_New();
+    Py_XSETREF(self->collations, PyDict_New());
     if (!self->collations) {
         return -1;
     }
@@ -242,7 +249,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
     /* Clean up if user has not called .close() explicitly. */
     if (self->db) {
         Py_BEGIN_ALLOW_THREADS
-        sqlite3_close(self->db);
+        SQLITE3_CLOSE(self->db);
         Py_END_ALLOW_THREADS
     }
 
@@ -335,7 +342,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
 
     if (self->db) {
         Py_BEGIN_ALLOW_THREADS
-        rc = sqlite3_close(self->db);
+        rc = SQLITE3_CLOSE(self->db);
         Py_END_ALLOW_THREADS
 
         if (rc != SQLITE_OK) {
@@ -401,8 +408,7 @@ error:
     if (PyErr_Occurred()) {
         return NULL;
     } else {
-        Py_INCREF(Py_None);
-        return Py_None;
+        Py_RETURN_NONE;
     }
 }
 
@@ -444,8 +450,7 @@ error:
     if (PyErr_Occurred()) {
         return NULL;
     } else {
-        Py_INCREF(Py_None);
-        return Py_None;
+        Py_RETURN_NONE;
     }
 }
 
@@ -488,8 +493,7 @@ error:
     if (PyErr_Occurred()) {
         return NULL;
     } else {
-        Py_INCREF(Py_None);
-        return Py_None;
+        Py_RETURN_NONE;
     }
 }
 
@@ -594,11 +598,9 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
     PyObject* py_retval = NULL;
     int ok;
 
-#ifdef WITH_THREAD
     PyGILState_STATE threadstate;
 
     threadstate = PyGILState_Ensure();
-#endif
 
     py_func = (PyObject*)sqlite3_user_data(context);
 
@@ -622,9 +624,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
         _sqlite3_result_error(context, "user-defined function raised exception", -1);
     }
 
-#ifdef WITH_THREAD
     PyGILState_Release(threadstate);
-#endif
 }
 
 static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
@@ -635,18 +635,16 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
     PyObject** aggregate_instance;
     PyObject* stepmethod = NULL;
 
-#ifdef WITH_THREAD
     PyGILState_STATE threadstate;
 
     threadstate = PyGILState_Ensure();
-#endif
 
     aggregate_class = (PyObject*)sqlite3_user_data(context);
 
     aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
 
-    if (*aggregate_instance == 0) {
-        *aggregate_instance = PyObject_CallFunction(aggregate_class, NULL);
+    if (*aggregate_instance == NULL) {
+        *aggregate_instance = _PyObject_CallNoArg(aggregate_class);
 
         if (PyErr_Occurred()) {
             *aggregate_instance = 0;
@@ -686,9 +684,7 @@ error:
     Py_XDECREF(stepmethod);
     Py_XDECREF(function_result);
 
-#ifdef WITH_THREAD
     PyGILState_Release(threadstate);
-#endif
 }
 
 void _pysqlite_final_callback(sqlite3_context* context)
@@ -700,11 +696,9 @@ void _pysqlite_final_callback(sqlite3_context* context)
     PyObject *exception, *value, *tb;
     int restore;
 
-#ifdef WITH_THREAD
     PyGILState_STATE threadstate;
 
     threadstate = PyGILState_Ensure();
-#endif
 
     aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
     if (!*aggregate_instance) {
@@ -748,12 +742,7 @@ void _pysqlite_final_callback(sqlite3_context* context)
     }
 
 error:
-#ifdef WITH_THREAD
     PyGILState_Release(threadstate);
-#endif
-    /* explicit return to avoid a compilation error if WITH_THREAD
-       is not defined */
-    return;
 }
 
 static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
@@ -886,11 +875,9 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
 {
     PyObject *ret;
     int rc;
-#ifdef WITH_THREAD
     PyGILState_STATE gilstate;
 
     gilstate = PyGILState_Ensure();
-#endif
 
     ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
 
@@ -919,9 +906,7 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
         Py_DECREF(ret);
     }
 
-#ifdef WITH_THREAD
     PyGILState_Release(gilstate);
-#endif
     return rc;
 }
 
@@ -929,12 +914,10 @@ static int _progress_handler(void* user_arg)
 {
     int rc;
     PyObject *ret;
-#ifdef WITH_THREAD
     PyGILState_STATE gilstate;
 
     gilstate = PyGILState_Ensure();
-#endif
-    ret = PyObject_CallFunction((PyObject*)user_arg, NULL);
+    ret = _PyObject_CallNoArg((PyObject*)user_arg);
 
     if (!ret) {
         if (_enable_callback_tracebacks) {
@@ -950,9 +933,7 @@ static int _progress_handler(void* user_arg)
         Py_DECREF(ret);
     }
 
-#ifdef WITH_THREAD
     PyGILState_Release(gilstate);
-#endif
     return rc;
 }
 
@@ -961,11 +942,9 @@ static void _trace_callback(void* user_arg, const char* statement_string)
     PyObject *py_statement = NULL;
     PyObject *ret = NULL;
 
-#ifdef WITH_THREAD
     PyGILState_STATE gilstate;
 
     gilstate = PyGILState_Ensure();
-#endif
     py_statement = PyUnicode_DecodeUTF8(statement_string,
             strlen(statement_string), "replace");
     if (py_statement) {
@@ -983,9 +962,7 @@ static void _trace_callback(void* user_arg, const char* statement_string)
         }
     }
 
-#ifdef WITH_THREAD
     PyGILState_Release(gilstate);
-#endif
 }
 
 static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
@@ -1122,18 +1099,16 @@ static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* ar
 
 int pysqlite_check_thread(pysqlite_Connection* self)
 {
-#ifdef WITH_THREAD
     if (self->check_same_thread) {
         if (PyThread_get_thread_ident() != self->thread_ident) {
             PyErr_Format(pysqlite_ProgrammingError,
-                        "SQLite objects created in a thread can only be used in that same thread."
-                        "The object was created in thread id %ld and this is thread id %ld",
+                        "SQLite objects created in a thread can only be used in that same thread. "
+                        "The object was created in thread id %lu and this is thread id %lu.",
                         self->thread_ident, PyThread_get_thread_ident());
             return 0;
         }
 
     }
-#endif
     return 1;
 }
 
@@ -1220,7 +1195,7 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py
         return NULL;
     }
 
-    if (!_PyArg_NoKeywords(MODULE_NAME ".Connection()", kwargs))
+    if (!_PyArg_NoKeywords(MODULE_NAME ".Connection", kwargs))
         return NULL;
 
     if (!PyArg_ParseTuple(args, "O", &sql))
@@ -1367,15 +1342,11 @@ pysqlite_collation_callback(
     PyObject* callback = (PyObject*)context;
     PyObject* string1 = 0;
     PyObject* string2 = 0;
-#ifdef WITH_THREAD
     PyGILState_STATE gilstate;
-#endif
     PyObject* retval = NULL;
     long longval;
     int result = 0;
-#ifdef WITH_THREAD
     gilstate = PyGILState_Ensure();
-#endif
 
     if (PyErr_Occurred()) {
         goto finally;
@@ -1411,9 +1382,7 @@ finally:
     Py_XDECREF(string1);
     Py_XDECREF(string2);
     Py_XDECREF(retval);
-#ifdef WITH_THREAD
     PyGILState_Release(gilstate);
-#endif
     return result;
 }
 
@@ -1481,6 +1450,153 @@ finally:
     return retval;
 }
 
+#ifdef HAVE_BACKUP_API
+static PyObject *
+pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *target = NULL;
+    int pages = -1;
+    PyObject *progress = Py_None;
+    const char *name = "main";
+    int rc;
+    int callback_error = 0;
+    PyObject *sleep_obj = NULL;
+    int sleep_ms = 250;
+    sqlite3 *bck_conn;
+    sqlite3_backup *bck_handle;
+    static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords,
+                                     &pysqlite_ConnectionType, &target,
+                                     &pages, &progress, &name, &sleep_obj)) {
+        return NULL;
+    }
+
+    if (sleep_obj != NULL) {
+        _PyTime_t sleep_secs;
+        if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj,
+                                      _PyTime_ROUND_CEILING)) {
+            return NULL;
+        }
+        _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs,
+                                              _PyTime_ROUND_CEILING);
+        if (ms < INT_MIN || ms > INT_MAX) {
+            PyErr_SetString(PyExc_OverflowError, "sleep is too large");
+            return NULL;
+        }
+        sleep_ms = (int)ms;
+    }
+
+    if (!pysqlite_check_connection((pysqlite_Connection *)target)) {
+        return NULL;
+    }
+
+    if ((pysqlite_Connection *)target == self) {
+        PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance");
+        return NULL;
+    }
+
+#if SQLITE_VERSION_NUMBER < 3008008
+    /* Since 3.8.8 this is already done, per commit
+       https://www.sqlite.org/src/info/169b5505498c0a7e */
+    if (!sqlite3_get_autocommit(((pysqlite_Connection *)target)->db)) {
+        PyErr_SetString(pysqlite_OperationalError, "target is in transaction");
+        return NULL;
+    }
+#endif
+
+    if (progress != Py_None && !PyCallable_Check(progress)) {
+        PyErr_SetString(PyExc_TypeError, "progress argument must be a callable");
+        return NULL;
+    }
+
+    if (pages == 0) {
+        pages = -1;
+    }
+
+    bck_conn = ((pysqlite_Connection *)target)->db;
+
+    Py_BEGIN_ALLOW_THREADS
+    bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name);
+    Py_END_ALLOW_THREADS
+
+    if (bck_handle) {
+        do {
+            Py_BEGIN_ALLOW_THREADS
+            rc = sqlite3_backup_step(bck_handle, pages);
+            Py_END_ALLOW_THREADS
+
+            if (progress != Py_None) {
+                PyObject *res;
+
+                res = PyObject_CallFunction(progress, "iii", rc,
+                                            sqlite3_backup_remaining(bck_handle),
+                                            sqlite3_backup_pagecount(bck_handle));
+                if (res == NULL) {
+                    /* User's callback raised an error: interrupt the loop and
+                       propagate it. */
+                    callback_error = 1;
+                    rc = -1;
+                } else {
+                    Py_DECREF(res);
+                }
+            }
+
+            /* Sleep for a while if there are still further pages to copy and
+               the engine could not make any progress */
+            if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
+                Py_BEGIN_ALLOW_THREADS
+                sqlite3_sleep(sleep_ms);
+                Py_END_ALLOW_THREADS
+            }
+        } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
+
+        Py_BEGIN_ALLOW_THREADS
+        rc = sqlite3_backup_finish(bck_handle);
+        Py_END_ALLOW_THREADS
+    } else {
+        rc = _pysqlite_seterror(bck_conn, NULL);
+    }
+
+    if (!callback_error && rc != SQLITE_OK) {
+        /* We cannot use _pysqlite_seterror() here because the backup APIs do
+           not set the error status on the connection object, but rather on
+           the backup handle. */
+        if (rc == SQLITE_NOMEM) {
+            (void)PyErr_NoMemory();
+        } else {
+#if SQLITE_VERSION_NUMBER > 3007015
+            PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc));
+#else
+            switch (rc) {
+                case SQLITE_READONLY:
+                    PyErr_SetString(pysqlite_OperationalError,
+                                    "attempt to write a readonly database");
+                    break;
+                case SQLITE_BUSY:
+                    PyErr_SetString(pysqlite_OperationalError, "database is locked");
+                    break;
+                case SQLITE_LOCKED:
+                    PyErr_SetString(pysqlite_OperationalError,
+                                    "database table is locked");
+                    break;
+                default:
+                    PyErr_Format(pysqlite_OperationalError,
+                                 "unrecognized error code: %d", rc);
+                    break;
+            }
+#endif
+        }
+    }
+
+    if (!callback_error && rc == SQLITE_OK) {
+        Py_RETURN_NONE;
+    } else {
+        return NULL;
+    }
+}
+#endif
+
 static PyObject *
 pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
 {
@@ -1490,7 +1606,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
     PyObject* retval;
     Py_ssize_t i, len;
     _Py_IDENTIFIER(upper);
-    char *uppercase_name_str;
+    const char *uppercase_name_str;
     int rc;
     unsigned int kind;
     void *data;
@@ -1584,7 +1700,7 @@ static PyObject *
 pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args)
 {
     PyObject* exc_type, *exc_value, *exc_tb;
-    char* method_name;
+    const char* method_name;
     PyObject* result;
 
     if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) {
@@ -1653,6 +1769,10 @@ static PyMethodDef connection_methods[] = {
         PyDoc_STR("Abort any pending database operation. Non-standard.")},
     {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS,
         PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")},
+    #ifdef HAVE_BACKUP_API
+    {"backup", (PyCFunction)pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS,
+        PyDoc_STR("Makes a backup of the database. Non-standard.")},
+    #endif
     {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS,
         PyDoc_STR("For context manager. Non-standard.")},
     {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS,
index 2860a0c6f9f297340dc5ceccb2fd69d8efda7f43..5fb410a62e53e92ede8be01ee174a2cb3f38d025 100644 (file)
@@ -61,7 +61,7 @@ typedef struct
     int initialized;
 
     /* thread identification of the thread the connection was created in */
-    long thread_ident;
+    unsigned long thread_ident;
 
     pysqlite_Cache* statement_cache;
 
index 3706cb2cd986e085e1242e3532900a2340951350..4ecb5b4b92c6310643a7043831a8d44a608a7a59 100644 (file)
@@ -538,6 +538,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
         rc = pysqlite_step(self->statement->st, self->connection);
         if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
             if (PyErr_Occurred()) {
+                /* there was an error that occurred in a user-defined callback */
                 if (_enable_callback_tracebacks) {
                     PyErr_Print();
                 } else {
@@ -558,7 +559,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
         Py_BEGIN_ALLOW_THREADS
         numcols = sqlite3_column_count(self->statement->st);
         Py_END_ALLOW_THREADS
-
         if (self->description == Py_None && numcols > 0) {
             Py_SETREF(self->description, PyTuple_New(numcols));
             if (!self->description) {
index 2261b8013ce53f9532fd0ee660fd02a51259a091..3d01872322c335050453a6646900c9a080db24a6 100644 (file)
@@ -33,7 +33,7 @@
 
 /** the adapters registry **/
 
-PyObject *psyco_adapters;
+static PyObject *psyco_adapters = NULL;
 
 /* pysqlite_microprotocols_init - initialize the adapters dictionary */
 
index 6941716c4cf73c71a46567451d067c7099e4fa15..99ff6f642b25eb338f5c75868f718885ef022c50 100644 (file)
 
 #include <Python.h>
 
-/** adapters registry **/
-
-extern PyObject *psyco_adapters;
-
 /** the names of the three mandatory methods **/
 
 #define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
index ed3367e5cfd98c18ee485e53395093d1626dbd6a..b64f8c8ab9dfd1c6ba42cf153e98c0ec518c624b 100644 (file)
 
 /* static objects at module-level */
 
-PyObject* pysqlite_Error, *pysqlite_Warning, *pysqlite_InterfaceError, *pysqlite_DatabaseError,
-    *pysqlite_InternalError, *pysqlite_OperationalError, *pysqlite_ProgrammingError,
-    *pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError;
-
-PyObject* converters;
-int _enable_callback_tracebacks;
-int pysqlite_BaseTypeAdapted;
+PyObject *pysqlite_Error = NULL;
+PyObject *pysqlite_Warning = NULL;
+PyObject *pysqlite_InterfaceError = NULL;
+PyObject *pysqlite_DatabaseError = NULL;
+PyObject *pysqlite_InternalError = NULL;
+PyObject *pysqlite_OperationalError = NULL;
+PyObject *pysqlite_ProgrammingError = NULL;
+PyObject *pysqlite_IntegrityError = NULL;
+PyObject *pysqlite_DataError = NULL;
+PyObject *pysqlite_NotSupportedError = NULL;
+
+PyObject* converters = NULL;
+int _enable_callback_tracebacks = 0;
+int pysqlite_BaseTypeAdapted = 0;
 
 static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
         kwargs)
@@ -55,7 +62,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
         "check_same_thread", "factory", "cached_statements", "uri", "flags",
         NULL
     };
-    char* database;
+    PyObject* database;
     int detect_types = 0;
     PyObject* isolation_level;
     PyObject* factory = NULL;
@@ -67,7 +74,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
 
     PyObject* result;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOipi", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOip", kwlist,
                                      &database, &timeout, &detect_types,
                                      &isolation_level, &check_same_thread,
                                      &factory, &cached_statements, &uri,
@@ -291,6 +298,15 @@ static const IntConstantPair _int_constants[] = {
     {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER},
     {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW},
     {"SQLITE_INSERT", SQLITE_INSERT},
+    {"SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE},
+    {"SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX},
+    {"SQLITE_OPEN_MEMORY", SQLITE_OPEN_MEMORY},
+    {"SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX},
+    {"SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE},
+    {"SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY},
+    {"SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE},
+    {"SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE},
+    {"SQLITE_OPEN_URI", SQLITE_OPEN_URI},
     {"SQLITE_PRAGMA", SQLITE_PRAGMA},
     {"SQLITE_READ", SQLITE_READ},
     {"SQLITE_SELECT", SQLITE_SELECT},
@@ -304,14 +320,30 @@ static const IntConstantPair _int_constants[] = {
 #endif
 #if SQLITE_VERSION_NUMBER >= 3003000
     {"SQLITE_ANALYZE", SQLITE_ANALYZE},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3003007
+    {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE},
+    {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3003008
+    {"SQLITE_FUNCTION", SQLITE_FUNCTION},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3006008
+    {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3008003
+    {"SQLITE_RECURSIVE", SQLITE_RECURSIVE},
+#endif
+#if SQLITE_VERSION_NUMBER >= 3006011
+    {"SQLITE_DONE", SQLITE_DONE},
 #endif
     {(char*)NULL, 0}
 };
 
 
-static struct PyModuleDef _sqlitemodule = {
+static struct PyModuleDef _sqlite3module = {
         PyModuleDef_HEAD_INIT,
-        "_sqlite",
+        "_sqlite3",
         NULL,
         -1,
         module_methods,
@@ -321,13 +353,13 @@ static struct PyModuleDef _sqlitemodule = {
         NULL
 };
 
-PyMODINIT_FUNC PyInit__sqlite(void)
+PyMODINIT_FUNC PyInit__sqlite3(void)
 {
     PyObject *module, *dict;
     PyObject *tmp_obj;
     int i;
 
-    module = PyModule_Create(&_sqlitemodule);
+    module = PyModule_Create(&_sqlite3module);
 
     if (!module ||
         (pysqlite_row_setup_types() < 0) ||
@@ -423,7 +455,7 @@ PyMODINIT_FUNC PyInit__sqlite(void)
     PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type);
 
     /* Set integer constants */
-    for (i = 0; _int_constants[i].constant_name != 0; i++) {
+    for (i = 0; _int_constants[i].constant_name != NULL; i++) {
         tmp_obj = PyLong_FromLong(_int_constants[i].constant_value);
         if (!tmp_obj) {
             goto error;
@@ -450,27 +482,6 @@ PyMODINIT_FUNC PyInit__sqlite(void)
     /* initialize the default converters */
     converters_init(dict);
 
-    _enable_callback_tracebacks = 0;
-
-    pysqlite_BaseTypeAdapted = 0;
-
-    /* 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
-     * thread is created using thread.start_new_thread() or fork() is
-     * called.  that would cause the ALLOW_THREADS here to segfault due
-     * to a null pointer reference if no threads or child processes
-     * have been created.  This works around that and is a no-op if
-     * threads have already been initialized.
-     *  (see pybsddb-users mailing list post on 2002-08-07)
-     */
-#ifdef WITH_THREAD
-    PyEval_InitThreads();
-#endif
-
 error:
     if (PyErr_Occurred())
     {
index 53342f3444c097bc9b1801596c672a0385ec8fa1..64872e8ddfc157ca834a892ee705e775b9d1385f 100644 (file)
--- a/src/row.c
+++ b/src/row.c
@@ -41,7 +41,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 
     assert(type != NULL && type->tp_alloc != NULL);
 
-    if (!_PyArg_NoKeywords("Row()", kwargs))
+    if (!_PyArg_NoKeywords("Row", kwargs))
         return NULL;
     if (!PyArg_ParseTuple(args, "OO", &cursor, &data))
         return NULL;
@@ -79,12 +79,12 @@ PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
 PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
 {
     Py_ssize_t _idx;
-    char* key;
+    const char *key;
     Py_ssize_t nitems, i;
-    char* compare_key;
+    const char *compare_key;
 
-    char* p1;
-    char* p2;
+    const char *p1;
+    const char *p2;
 
     PyObject* item;
 
@@ -155,7 +155,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa
     return PyTuple_GET_SIZE(self->data);
 }
 
-PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
+PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored))
 {
     PyObject* list;
     Py_ssize_t nitems, i;
index c7cf4237e56bd5de1299dd65081cc6232cd8e780..38690884227e68a9b85ad11d83d869cd04870187 100644 (file)
@@ -114,7 +114,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
 int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)
 {
     int rc = SQLITE_OK;
-    char* string;
+    const char *string;
     Py_ssize_t buflen;
     parameter_type paramtype;
 
index bff6865166ad0e9d0382d7f683783d2547312c78..3fa671d052b0d83c28cdbb6491e5f60300da11d9 100644 (file)
@@ -47,11 +47,6 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection)
  */
 int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
 {
-    /* SQLite often doesn't report anything useful, unless you reset the statement first */
-    if (st != NULL) {
-        (void)sqlite3_reset(st);
-    }
-
     int errorcode = sqlite3_errcode(db);
 
     switch (errorcode)
index 88ea90689d518c0e92f771b635acb9e763c822fa..abaefd8b87b8646ce9ff0fae34d8247851e8bd17 100644 (file)
@@ -39,4 +39,10 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
 PyObject * _pysqlite_long_from_int64(sqlite_int64 value);
 sqlite_int64 _pysqlite_long_as_int64(PyObject * value);
 
+#if SQLITE_VERSION_NUMBER >= 3007014
+#define SQLITE3_CLOSE sqlite3_close_v2
+#else
+#define SQLITE3_CLOSE sqlite3_close
+#endif
+
 #endif