mirror of https://github.com/python/cpython
Update to pysqlite 2.2.0
This commit is contained in:
parent
a058836e96
commit
72289a616c
|
@ -268,6 +268,12 @@ class CursorTests(unittest.TestCase):
|
||||||
self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
|
self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
|
||||||
self.failUnlessEqual(self.cu.rowcount, 3)
|
self.failUnlessEqual(self.cu.rowcount, 3)
|
||||||
|
|
||||||
|
def CheckTotalChanges(self):
|
||||||
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
|
if self.cx.total_changes < 2:
|
||||||
|
self.fail("total changes reported wrong value")
|
||||||
|
|
||||||
# Checks for executemany:
|
# Checks for executemany:
|
||||||
# Sequences are required by the DB-API, iterators
|
# Sequences are required by the DB-API, iterators
|
||||||
# enhancements in pysqlite.
|
# enhancements in pysqlite.
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#-*- coding: ISO-8859-1 -*-
|
||||||
|
# pysqlite2/test/hooks.py: tests for various SQLite-specific hooks
|
||||||
|
#
|
||||||
|
# Copyright (C) 2006 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.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
import os, unittest
|
||||||
|
import pysqlite2.dbapi2 as sqlite
|
||||||
|
|
||||||
|
class CollationTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def CheckCreateCollationNotCallable(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
try:
|
||||||
|
con.create_collation("X", 42)
|
||||||
|
self.fail("should have raised a TypeError")
|
||||||
|
except TypeError, e:
|
||||||
|
self.failUnlessEqual(e.args[0], "parameter must be callable")
|
||||||
|
|
||||||
|
def CheckCreateCollationNotAscii(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
try:
|
||||||
|
con.create_collation("collä", cmp)
|
||||||
|
self.fail("should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def CheckCollationIsUsed(self):
|
||||||
|
def mycoll(x, y):
|
||||||
|
# reverse order
|
||||||
|
return -cmp(x, y)
|
||||||
|
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.create_collation("mycoll", mycoll)
|
||||||
|
sql = """
|
||||||
|
select x from (
|
||||||
|
select 'a' as x
|
||||||
|
union
|
||||||
|
select 'b' as x
|
||||||
|
union
|
||||||
|
select 'c' as x
|
||||||
|
) order by x collate mycoll
|
||||||
|
"""
|
||||||
|
result = con.execute(sql).fetchall()
|
||||||
|
if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a":
|
||||||
|
self.fail("the expected order was not returned")
|
||||||
|
|
||||||
|
con.create_collation("mycoll", None)
|
||||||
|
try:
|
||||||
|
result = con.execute(sql).fetchall()
|
||||||
|
self.fail("should have raised an OperationalError")
|
||||||
|
except sqlite.OperationalError, e:
|
||||||
|
self.failUnlessEqual(e.args[0], "no such collation sequence: mycoll")
|
||||||
|
|
||||||
|
def CheckCollationRegisterTwice(self):
|
||||||
|
"""
|
||||||
|
Register two different collation functions under the same name.
|
||||||
|
Verify that the last one is actually used.
|
||||||
|
"""
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.create_collation("mycoll", cmp)
|
||||||
|
con.create_collation("mycoll", lambda x, y: -cmp(x, y))
|
||||||
|
result = con.execute("""
|
||||||
|
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
|
||||||
|
""").fetchall()
|
||||||
|
if result[0][0] != 'b' or result[1][0] != 'a':
|
||||||
|
self.fail("wrong collation function is used")
|
||||||
|
|
||||||
|
def CheckDeregisterCollation(self):
|
||||||
|
"""
|
||||||
|
Register a collation, then deregister it. Make sure an error is raised if we try
|
||||||
|
to use it.
|
||||||
|
"""
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.create_collation("mycoll", cmp)
|
||||||
|
con.create_collation("mycoll", None)
|
||||||
|
try:
|
||||||
|
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
|
||||||
|
self.fail("should have raised an OperationalError")
|
||||||
|
except sqlite.OperationalError, e:
|
||||||
|
if not e.args[0].startswith("no such collation sequence"):
|
||||||
|
self.fail("wrong OperationalError raised")
|
||||||
|
|
||||||
|
def suite():
|
||||||
|
collation_suite = unittest.makeSuite(CollationTests, "Check")
|
||||||
|
return unittest.TestSuite((collation_suite,))
|
||||||
|
|
||||||
|
def test():
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(suite())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test()
|
|
@ -0,0 +1,48 @@
|
||||||
|
#-*- coding: ISO-8859-1 -*-
|
||||||
|
# pysqlite2/test/regression.py: pysqlite regression tests
|
||||||
|
#
|
||||||
|
# Copyright (C) 2006 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.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import pysqlite2.dbapi2 as sqlite
|
||||||
|
|
||||||
|
class RegressionTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.con = sqlite.connect(":memory:")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.con.close()
|
||||||
|
|
||||||
|
def CheckPragmaUserVersion(self):
|
||||||
|
# This used to crash pysqlite because this pragma command returns NULL for the column name
|
||||||
|
cur = self.con.cursor()
|
||||||
|
cur.execute("pragma user_version")
|
||||||
|
|
||||||
|
def suite():
|
||||||
|
regression_suite = unittest.makeSuite(RegressionTests, "Check")
|
||||||
|
return unittest.TestSuite((regression_suite,))
|
||||||
|
|
||||||
|
def test():
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(suite())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test()
|
|
@ -25,7 +25,7 @@ import os, unittest
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
|
|
||||||
def get_db_path():
|
def get_db_path():
|
||||||
return "testdb"
|
return "sqlite_testdb"
|
||||||
|
|
||||||
class TransactionTests(unittest.TestCase):
|
class TransactionTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -47,6 +47,8 @@ class TransactionTests(unittest.TestCase):
|
||||||
self.cur2.close()
|
self.cur2.close()
|
||||||
self.con2.close()
|
self.con2.close()
|
||||||
|
|
||||||
|
os.unlink(get_db_path())
|
||||||
|
|
||||||
def CheckDMLdoesAutoCommitBefore(self):
|
def CheckDMLdoesAutoCommitBefore(self):
|
||||||
self.cur1.execute("create table test(i)")
|
self.cur1.execute("create table test(i)")
|
||||||
self.cur1.execute("insert into test(i) values (5)")
|
self.cur1.execute("insert into test(i) values (5)")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* cache .c - a LRU cache
|
/* cache .c - a LRU cache
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -29,7 +29,6 @@ Node* new_node(PyObject* key, PyObject* data)
|
||||||
Node* node;
|
Node* node;
|
||||||
|
|
||||||
node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
|
node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
|
||||||
/*node = PyObject_New(Node, &NodeType);*/
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,12 @@ int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
|
||||||
self->size = size;
|
self->size = size;
|
||||||
self->first = NULL;
|
self->first = NULL;
|
||||||
self->last = NULL;
|
self->last = NULL;
|
||||||
|
|
||||||
self->mapping = PyDict_New();
|
self->mapping = PyDict_New();
|
||||||
|
if (!self->mapping) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(factory);
|
Py_INCREF(factory);
|
||||||
self->factory = factory;
|
self->factory = factory;
|
||||||
|
|
||||||
|
@ -108,16 +112,11 @@ void cache_dealloc(Cache* self)
|
||||||
|
|
||||||
PyObject* cache_get(Cache* self, PyObject* args)
|
PyObject* cache_get(Cache* self, PyObject* args)
|
||||||
{
|
{
|
||||||
PyObject* key;
|
PyObject* key = args;
|
||||||
Node* node;
|
Node* node;
|
||||||
Node* ptr;
|
Node* ptr;
|
||||||
PyObject* data;
|
PyObject* data;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &key))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = (Node*)PyDict_GetItem(self->mapping, key);
|
node = (Node*)PyDict_GetItem(self->mapping, key);
|
||||||
if (node) {
|
if (node) {
|
||||||
node->count++;
|
node->count++;
|
||||||
|
@ -153,7 +152,11 @@ PyObject* cache_get(Cache* self, PyObject* args)
|
||||||
if (PyDict_Size(self->mapping) == self->size) {
|
if (PyDict_Size(self->mapping) == self->size) {
|
||||||
if (self->last) {
|
if (self->last) {
|
||||||
node = self->last;
|
node = self->last;
|
||||||
PyDict_DelItem(self->mapping, self->last->key);
|
|
||||||
|
if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->prev) {
|
if (node->prev) {
|
||||||
node->prev->next = NULL;
|
node->prev->next = NULL;
|
||||||
}
|
}
|
||||||
|
@ -171,17 +174,24 @@ PyObject* cache_get(Cache* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
node = new_node(key, data);
|
node = new_node(key, data);
|
||||||
|
if (!node) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
node->prev = self->last;
|
node->prev = self->last;
|
||||||
|
|
||||||
Py_DECREF(data);
|
Py_DECREF(data);
|
||||||
|
|
||||||
|
if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
|
||||||
|
Py_DECREF(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->last) {
|
if (self->last) {
|
||||||
self->last->next = node;
|
self->last->next = node;
|
||||||
} else {
|
} else {
|
||||||
self->first = node;
|
self->first = node;
|
||||||
}
|
}
|
||||||
self->last = node;
|
self->last = node;
|
||||||
PyDict_SetItem(self->mapping, key, (PyObject*)node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(node->data);
|
Py_INCREF(node->data);
|
||||||
|
@ -215,10 +225,19 @@ PyObject* cache_display(Cache* self, PyObject* args)
|
||||||
Py_INCREF(nextkey);
|
Py_INCREF(nextkey);
|
||||||
|
|
||||||
fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
|
fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
|
||||||
|
if (!fmt_args) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
template = PyString_FromString("%s <- %s ->%s\n");
|
template = PyString_FromString("%s <- %s ->%s\n");
|
||||||
|
if (!template) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
display_str = PyString_Format(template, fmt_args);
|
display_str = PyString_Format(template, fmt_args);
|
||||||
Py_DECREF(template);
|
Py_DECREF(template);
|
||||||
Py_DECREF(fmt_args);
|
Py_DECREF(fmt_args);
|
||||||
|
if (!display_str) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
PyObject_Print(display_str, stdout, Py_PRINT_RAW);
|
PyObject_Print(display_str, stdout, Py_PRINT_RAW);
|
||||||
Py_DECREF(display_str);
|
Py_DECREF(display_str);
|
||||||
|
|
||||||
|
@ -233,7 +252,7 @@ PyObject* cache_display(Cache* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef cache_methods[] = {
|
static PyMethodDef cache_methods[] = {
|
||||||
{"get", (PyCFunction)cache_get, METH_VARARGS,
|
{"get", (PyCFunction)cache_get, METH_O,
|
||||||
PyDoc_STR("Gets an entry from the cache.")},
|
PyDoc_STR("Gets an entry from the cache.")},
|
||||||
{"display", (PyCFunction)cache_display, METH_NOARGS,
|
{"display", (PyCFunction)cache_display, METH_NOARGS,
|
||||||
PyDoc_STR("For debugging only.")},
|
PyDoc_STR("For debugging only.")},
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "prepare_protocol.h"
|
#include "prepare_protocol.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
|
|
||||||
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
|
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
|
||||||
|
@ -101,6 +103,14 @@ int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
|
||||||
self->check_same_thread = check_same_thread;
|
self->check_same_thread = check_same_thread;
|
||||||
|
|
||||||
self->function_pinboard = PyDict_New();
|
self->function_pinboard = PyDict_New();
|
||||||
|
if (!self->function_pinboard) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->collations = PyDict_New();
|
||||||
|
if (!self->collations) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
self->Warning = Warning;
|
self->Warning = Warning;
|
||||||
self->Error = Error;
|
self->Error = Error;
|
||||||
|
@ -167,6 +177,7 @@ void connection_dealloc(Connection* self)
|
||||||
Py_XDECREF(self->function_pinboard);
|
Py_XDECREF(self->function_pinboard);
|
||||||
Py_XDECREF(self->row_factory);
|
Py_XDECREF(self->row_factory);
|
||||||
Py_XDECREF(self->text_factory);
|
Py_XDECREF(self->text_factory);
|
||||||
|
Py_XDECREF(self->collations);
|
||||||
|
|
||||||
self->ob_type->tp_free((PyObject*)self);
|
self->ob_type->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
@ -420,6 +431,9 @@ PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** a
|
||||||
void* raw_buffer;
|
void* raw_buffer;
|
||||||
|
|
||||||
args = PyTuple_New(argc);
|
args = PyTuple_New(argc);
|
||||||
|
if (!args) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
cur_value = argv[i];
|
cur_value = argv[i];
|
||||||
|
@ -655,6 +669,15 @@ static PyObject* connection_get_isolation_level(Connection* self, void* unused)
|
||||||
return self->isolation_level;
|
return self->isolation_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject* connection_get_total_changes(Connection* self, void* unused)
|
||||||
|
{
|
||||||
|
if (!check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return Py_BuildValue("i", sqlite3_total_changes(self->db));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
|
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
|
||||||
{
|
{
|
||||||
PyObject* empty;
|
PyObject* empty;
|
||||||
|
@ -669,7 +692,13 @@ static int connection_set_isolation_level(Connection* self, PyObject* isolation_
|
||||||
self->isolation_level = Py_None;
|
self->isolation_level = Py_None;
|
||||||
|
|
||||||
empty = PyTuple_New(0);
|
empty = PyTuple_New(0);
|
||||||
|
if (!empty) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
res = connection_commit(self, empty);
|
res = connection_commit(self, empty);
|
||||||
|
if (!res) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Py_DECREF(empty);
|
Py_DECREF(empty);
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
|
||||||
|
@ -825,11 +854,134 @@ error:
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------- COLLATION CODE ------------------------ */
|
||||||
|
|
||||||
|
static int
|
||||||
|
collation_callback(
|
||||||
|
void* context,
|
||||||
|
int text1_length, const void* text1_data,
|
||||||
|
int text2_length, const void* text2_data)
|
||||||
|
{
|
||||||
|
PyObject* callback = (PyObject*)context;
|
||||||
|
PyObject* string1 = 0;
|
||||||
|
PyObject* string2 = 0;
|
||||||
|
PyGILState_STATE gilstate;
|
||||||
|
|
||||||
|
PyObject* retval = NULL;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length);
|
||||||
|
string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length);
|
||||||
|
|
||||||
|
if (!string1 || !string2) {
|
||||||
|
goto finally; /* failed to allocate strings */
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL);
|
||||||
|
|
||||||
|
if (!retval) {
|
||||||
|
/* execution failed */
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PyInt_AsLong(retval);
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
finally:
|
||||||
|
Py_XDECREF(string1);
|
||||||
|
Py_XDECREF(string2);
|
||||||
|
Py_XDECREF(retval);
|
||||||
|
|
||||||
|
PyGILState_Release(gilstate);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
connection_create_collation(Connection* self, PyObject* args)
|
||||||
|
{
|
||||||
|
PyObject* callable;
|
||||||
|
PyObject* uppercase_name = 0;
|
||||||
|
PyObject* name;
|
||||||
|
PyObject* retval;
|
||||||
|
char* chk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!check_thread(self) || !check_connection(self)) {
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) {
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
uppercase_name = PyObject_CallMethod(name, "upper", "");
|
||||||
|
if (!uppercase_name) {
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
chk = PyString_AsString(uppercase_name);
|
||||||
|
while (*chk) {
|
||||||
|
if ((*chk >= '0' && *chk <= '9')
|
||||||
|
|| (*chk >= 'A' && *chk <= 'Z')
|
||||||
|
|| (*chk == '_'))
|
||||||
|
{
|
||||||
|
chk++;
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(ProgrammingError, "invalid character in collation name");
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callable != Py_None && !PyCallable_Check(callable)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callable != Py_None) {
|
||||||
|
PyDict_SetItem(self->collations, uppercase_name, callable);
|
||||||
|
} else {
|
||||||
|
PyDict_DelItem(self->collations, uppercase_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_create_collation(self->db,
|
||||||
|
PyString_AsString(uppercase_name),
|
||||||
|
SQLITE_UTF8,
|
||||||
|
(callable != Py_None) ? callable : NULL,
|
||||||
|
(callable != Py_None) ? collation_callback : NULL);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
PyDict_DelItem(self->collations, uppercase_name);
|
||||||
|
_seterror(self->db);
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
finally:
|
||||||
|
Py_XDECREF(uppercase_name);
|
||||||
|
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
retval = NULL;
|
||||||
|
} else {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
retval = Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static char connection_doc[] =
|
static char connection_doc[] =
|
||||||
PyDoc_STR("<missing docstring>");
|
PyDoc_STR("<missing docstring>");
|
||||||
|
|
||||||
static PyGetSetDef connection_getset[] = {
|
static PyGetSetDef connection_getset[] = {
|
||||||
{"isolation_level", (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
|
{"isolation_level", (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
|
||||||
|
{"total_changes", (getter)connection_get_total_changes, (setter)0},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -852,6 +1004,8 @@ static PyMethodDef connection_methods[] = {
|
||||||
PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")},
|
PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")},
|
||||||
{"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
|
{"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
|
||||||
PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
|
PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
|
||||||
|
{"create_collation", (PyCFunction)connection_create_collation, METH_VARARGS,
|
||||||
|
PyDoc_STR("Creates a collation function.")},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ typedef struct
|
||||||
* in connection_dealloc */
|
* in connection_dealloc */
|
||||||
PyObject* function_pinboard;
|
PyObject* function_pinboard;
|
||||||
|
|
||||||
|
/* a dictionary of registered collation name => collation callable mappings */
|
||||||
|
PyObject* collations;
|
||||||
|
|
||||||
/* Exception objects */
|
/* Exception objects */
|
||||||
PyObject* Warning;
|
PyObject* Warning;
|
||||||
PyObject* Error;
|
PyObject* Error;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
|
/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
|
||||||
#define INT32_MIN (-2147483647 - 1)
|
#define INT32_MIN (-2147483647 - 1)
|
||||||
|
@ -84,6 +85,9 @@ int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs)
|
||||||
self->next_row = NULL;
|
self->next_row = NULL;
|
||||||
|
|
||||||
self->row_cast_map = PyList_New(0);
|
self->row_cast_map = PyList_New(0);
|
||||||
|
if (!self->row_cast_map) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
self->description = Py_None;
|
self->description = Py_None;
|
||||||
|
@ -94,6 +98,9 @@ int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs)
|
||||||
self->arraysize = 1;
|
self->arraysize = 1;
|
||||||
|
|
||||||
self->rowcount = PyInt_FromLong(-1L);
|
self->rowcount = PyInt_FromLong(-1L);
|
||||||
|
if (!self->rowcount) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
self->row_factory = Py_None;
|
self->row_factory = Py_None;
|
||||||
|
@ -126,7 +133,7 @@ void cursor_dealloc(Cursor* self)
|
||||||
self->ob_type->tp_free((PyObject*)self);
|
self->ob_type->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_row_cast_map(Cursor* self)
|
int build_row_cast_map(Cursor* self)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char* type_start = (const char*)-1;
|
const char* type_start = (const char*)-1;
|
||||||
|
@ -139,10 +146,10 @@ void build_row_cast_map(Cursor* self)
|
||||||
PyObject* key;
|
PyObject* key;
|
||||||
|
|
||||||
if (!self->connection->detect_types) {
|
if (!self->connection->detect_types) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(self->row_cast_map);
|
Py_XDECREF(self->row_cast_map);
|
||||||
self->row_cast_map = PyList_New(0);
|
self->row_cast_map = PyList_New(0);
|
||||||
|
|
||||||
for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
|
for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
|
||||||
|
@ -156,6 +163,13 @@ void build_row_cast_map(Cursor* self)
|
||||||
type_start = pos + 1;
|
type_start = pos + 1;
|
||||||
} else if (*pos == ']' && type_start != (const char*)-1) {
|
} else if (*pos == ']' && type_start != (const char*)-1) {
|
||||||
key = PyString_FromStringAndSize(type_start, pos - type_start);
|
key = PyString_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
|
||||||
|
* no converter and proceed */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
converter = PyDict_GetItem(converters, key);
|
converter = PyDict_GetItem(converters, key);
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
break;
|
break;
|
||||||
|
@ -170,6 +184,9 @@ void build_row_cast_map(Cursor* self)
|
||||||
for (pos = decltype;;pos++) {
|
for (pos = decltype;;pos++) {
|
||||||
if (*pos == ' ' || *pos == 0) {
|
if (*pos == ' ' || *pos == 0) {
|
||||||
py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
|
py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
|
||||||
|
if (!py_decltype) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,18 +196,33 @@ void build_row_cast_map(Cursor* self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (converter) {
|
if (!converter) {
|
||||||
PyList_Append(self->row_cast_map, converter);
|
converter = Py_None;
|
||||||
} else {
|
}
|
||||||
PyList_Append(self->row_cast_map, Py_None);
|
|
||||||
|
if (PyList_Append(self->row_cast_map, converter) != 0) {
|
||||||
|
if (converter != Py_None) {
|
||||||
|
Py_DECREF(converter);
|
||||||
|
}
|
||||||
|
Py_XDECREF(self->row_cast_map);
|
||||||
|
self->row_cast_map = NULL;
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _build_column_name(const char* colname)
|
PyObject* _build_column_name(const char* colname)
|
||||||
{
|
{
|
||||||
const char* pos;
|
const char* pos;
|
||||||
|
|
||||||
|
if (!colname) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
for (pos = colname;; pos++) {
|
for (pos = colname;; pos++) {
|
||||||
if (*pos == 0 || *pos == ' ') {
|
if (*pos == 0 || *pos == ' ') {
|
||||||
return PyString_FromStringAndSize(colname, pos - colname);
|
return PyString_FromStringAndSize(colname, pos - colname);
|
||||||
|
@ -250,6 +282,9 @@ PyObject* _fetch_one_row(Cursor* self)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
row = PyTuple_New(numcols);
|
row = PyTuple_New(numcols);
|
||||||
|
if (!row) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < numcols; i++) {
|
for (i = 0; i < numcols; i++) {
|
||||||
if (self->connection->detect_types) {
|
if (self->connection->detect_types) {
|
||||||
|
@ -268,6 +303,9 @@ PyObject* _fetch_one_row(Cursor* self)
|
||||||
converted = Py_None;
|
converted = Py_None;
|
||||||
} else {
|
} else {
|
||||||
item = PyString_FromString(val_str);
|
item = PyString_FromString(val_str);
|
||||||
|
if (!item) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
converted = PyObject_CallFunction(converter, "O", item);
|
converted = PyObject_CallFunction(converter, "O", item);
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
/* TODO: have a way to log these errors */
|
/* TODO: have a way to log these errors */
|
||||||
|
@ -404,10 +442,16 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
|
|
||||||
if (second_argument == NULL) {
|
if (second_argument == NULL) {
|
||||||
second_argument = PyTuple_New(0);
|
second_argument = PyTuple_New(0);
|
||||||
|
if (!second_argument) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Py_INCREF(second_argument);
|
Py_INCREF(second_argument);
|
||||||
}
|
}
|
||||||
PyList_Append(parameters_list, second_argument);
|
if (PyList_Append(parameters_list, second_argument) != 0) {
|
||||||
|
Py_DECREF(second_argument);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Py_DECREF(second_argument);
|
Py_DECREF(second_argument);
|
||||||
|
|
||||||
parameters_iter = PyObject_GetIter(parameters_list);
|
parameters_iter = PyObject_GetIter(parameters_list);
|
||||||
|
@ -436,6 +480,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
|
|
||||||
Py_DECREF(self->rowcount);
|
Py_DECREF(self->rowcount);
|
||||||
self->rowcount = PyInt_FromLong(-1L);
|
self->rowcount = PyInt_FromLong(-1L);
|
||||||
|
if (!self->rowcount) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
statement_type = detect_statement_type(operation_cstr);
|
statement_type = detect_statement_type(operation_cstr);
|
||||||
if (self->connection->begin_statement) {
|
if (self->connection->begin_statement) {
|
||||||
|
@ -457,6 +504,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
- we better COMMIT first so it works for all cases */
|
- we better COMMIT first so it works for all cases */
|
||||||
if (self->connection->inTransaction) {
|
if (self->connection->inTransaction) {
|
||||||
func_args = PyTuple_New(0);
|
func_args = PyTuple_New(0);
|
||||||
|
if (!func_args) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
result = connection_commit(self->connection, func_args);
|
result = connection_commit(self->connection, func_args);
|
||||||
Py_DECREF(func_args);
|
Py_DECREF(func_args);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -471,12 +521,18 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
"You cannot execute SELECT statements in executemany().");
|
"You cannot execute SELECT statements in executemany().");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func_args = PyTuple_New(1);
|
func_args = PyTuple_New(1);
|
||||||
|
if (!func_args) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
Py_INCREF(operation);
|
Py_INCREF(operation);
|
||||||
PyTuple_SetItem(func_args, 0, operation);
|
if (PyTuple_SetItem(func_args, 0, operation) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->statement) {
|
if (self->statement) {
|
||||||
(void)statement_reset(self->statement);
|
(void)statement_reset(self->statement);
|
||||||
|
@ -493,6 +549,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
if (self->statement->in_use) {
|
if (self->statement->in_use) {
|
||||||
Py_DECREF(self->statement);
|
Py_DECREF(self->statement);
|
||||||
self->statement = PyObject_New(Statement, &StatementType);
|
self->statement = PyObject_New(Statement, &StatementType);
|
||||||
|
if (!self->statement) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
rc = statement_create(self->statement, self->connection, operation);
|
rc = statement_create(self->statement, self->connection, operation);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
self->statement = 0;
|
self->statement = 0;
|
||||||
|
@ -516,7 +575,10 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
build_row_cast_map(self);
|
if (build_row_cast_map(self) != 0) {
|
||||||
|
PyErr_SetString(OperationalError, "Error while building row_cast_map");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
|
rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
|
||||||
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
|
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
|
||||||
|
@ -543,8 +605,14 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
|
||||||
if (self->description == Py_None) {
|
if (self->description == Py_None) {
|
||||||
Py_DECREF(self->description);
|
Py_DECREF(self->description);
|
||||||
self->description = PyTuple_New(numcols);
|
self->description = PyTuple_New(numcols);
|
||||||
|
if (!self->description) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
for (i = 0; i < numcols; i++) {
|
for (i = 0; i < numcols; i++) {
|
||||||
descriptor = PyTuple_New(7);
|
descriptor = PyTuple_New(7);
|
||||||
|
if (!descriptor) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i)));
|
PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i)));
|
||||||
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
|
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
|
||||||
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
|
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
|
||||||
|
@ -608,8 +676,8 @@ error:
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(self);
|
||||||
return Py_None;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,6 +726,9 @@ PyObject* cursor_executescript(Cursor* self, PyObject* args)
|
||||||
|
|
||||||
/* commit first */
|
/* commit first */
|
||||||
func_args = PyTuple_New(0);
|
func_args = PyTuple_New(0);
|
||||||
|
if (!func_args) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
result = connection_commit(self->connection, func_args);
|
result = connection_commit(self->connection, func_args);
|
||||||
Py_DECREF(func_args);
|
Py_DECREF(func_args);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -710,8 +781,8 @@ error:
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(self);
|
||||||
return Py_None;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,9 +860,12 @@ PyObject* cursor_fetchmany(Cursor* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
list = PyList_New(0);
|
list = PyList_New(0);
|
||||||
|
if (!list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* just make sure we enter the loop */
|
/* just make sure we enter the loop */
|
||||||
row = (PyObject*)1;
|
row = Py_None;
|
||||||
|
|
||||||
while (row) {
|
while (row) {
|
||||||
row = cursor_iternext(self);
|
row = cursor_iternext(self);
|
||||||
|
@ -821,9 +895,12 @@ PyObject* cursor_fetchall(Cursor* self, PyObject* args)
|
||||||
PyObject* list;
|
PyObject* list;
|
||||||
|
|
||||||
list = PyList_New(0);
|
list = PyList_New(0);
|
||||||
|
if (!list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* just make sure we enter the loop */
|
/* just make sure we enter the loop */
|
||||||
row = (PyObject*)1;
|
row = (PyObject*)Py_None;
|
||||||
|
|
||||||
while (row) {
|
while (row) {
|
||||||
row = cursor_iternext(self);
|
row = cursor_iternext(self);
|
||||||
|
|
|
@ -45,9 +45,7 @@ microprotocols_init(PyObject *dict)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDict_SetItemString(dict, "adapters", psyco_adapters);
|
return PyDict_SetItemString(dict, "adapters", psyco_adapters);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,8 +63,17 @@ microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
|
||||||
cast, type->tp_name);
|
cast, type->tp_name);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
|
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
|
||||||
PyDict_SetItem(psyco_adapters, key, cast);
|
if (!key) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyDict_SetItem(psyco_adapters, key, cast) != 0) {
|
||||||
|
Py_DECREF(key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -85,6 +92,9 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
|
|
||||||
/* look for an adapter in the registry */
|
/* look for an adapter in the registry */
|
||||||
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
|
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
|
||||||
|
if (!key) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
adapter = PyDict_GetItem(psyco_adapters, key);
|
adapter = PyDict_GetItem(psyco_adapters, key);
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
|
|
|
@ -39,9 +39,6 @@ PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
|
||||||
*OperationalError, *ProgrammingError, *IntegrityError, *DataError,
|
*OperationalError, *ProgrammingError, *IntegrityError, *DataError,
|
||||||
*NotSupportedError, *OptimizedUnicode;
|
*NotSupportedError, *OptimizedUnicode;
|
||||||
|
|
||||||
PyObject* time_time;
|
|
||||||
PyObject* time_sleep;
|
|
||||||
|
|
||||||
PyObject* converters;
|
PyObject* converters;
|
||||||
|
|
||||||
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
|
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
|
||||||
|
@ -150,7 +147,9 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObj
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDict_SetItem(converters, name, callable);
|
if (PyDict_SetItem(converters, name, callable) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -159,6 +158,9 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObj
|
||||||
void converters_init(PyObject* dict)
|
void converters_init(PyObject* dict)
|
||||||
{
|
{
|
||||||
converters = PyDict_New();
|
converters = PyDict_New();
|
||||||
|
if (!converters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PyDict_SetItemString(dict, "converters", converters);
|
PyDict_SetItemString(dict, "converters", converters);
|
||||||
}
|
}
|
||||||
|
@ -169,8 +171,8 @@ static PyMethodDef module_methods[] = {
|
||||||
#ifdef HAVE_SHARED_CACHE
|
#ifdef HAVE_SHARED_CACHE
|
||||||
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread.")},
|
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread.")},
|
||||||
#endif
|
#endif
|
||||||
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry.")},
|
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with sqlite's adapter registry.")},
|
||||||
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite.")},
|
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with sqlite.")},
|
||||||
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
|
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -178,11 +180,11 @@ static PyMethodDef module_methods[] = {
|
||||||
PyMODINIT_FUNC init_sqlite3(void)
|
PyMODINIT_FUNC init_sqlite3(void)
|
||||||
{
|
{
|
||||||
PyObject *module, *dict;
|
PyObject *module, *dict;
|
||||||
PyObject* time_module;
|
PyObject *tmp_obj;
|
||||||
|
|
||||||
module = Py_InitModule("_sqlite3", module_methods);
|
module = Py_InitModule("_sqlite3", module_methods);
|
||||||
|
|
||||||
if (
|
if (!module ||
|
||||||
(row_setup_types() < 0) ||
|
(row_setup_types() < 0) ||
|
||||||
(cursor_setup_types() < 0) ||
|
(cursor_setup_types() < 0) ||
|
||||||
(connection_setup_types() < 0) ||
|
(connection_setup_types() < 0) ||
|
||||||
|
@ -206,56 +208,93 @@ PyMODINIT_FUNC init_sqlite3(void)
|
||||||
Py_INCREF(&RowType);
|
Py_INCREF(&RowType);
|
||||||
PyModule_AddObject(module, "Row", (PyObject*) &RowType);
|
PyModule_AddObject(module, "Row", (PyObject*) &RowType);
|
||||||
|
|
||||||
if (!(dict = PyModule_GetDict(module)))
|
if (!(dict = PyModule_GetDict(module))) {
|
||||||
{
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Create DB-API Exception hierarchy */
|
/*** Create DB-API Exception hierarchy */
|
||||||
|
|
||||||
Error = PyErr_NewException("sqlite3.Error", PyExc_StandardError, NULL);
|
if (!(Error = PyErr_NewException("sqlite3.Error", PyExc_StandardError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "Error", Error);
|
PyDict_SetItemString(dict, "Error", Error);
|
||||||
|
|
||||||
Warning = PyErr_NewException("sqlite3.Warning", PyExc_StandardError, NULL);
|
if (!(Warning = PyErr_NewException("sqlite3.Warning", PyExc_StandardError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "Warning", Warning);
|
PyDict_SetItemString(dict, "Warning", Warning);
|
||||||
|
|
||||||
/* Error subclasses */
|
/* Error subclasses */
|
||||||
|
|
||||||
InterfaceError = PyErr_NewException("sqlite3.InterfaceError", Error, NULL);
|
if (!(InterfaceError = PyErr_NewException("sqlite3.InterfaceError", Error, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
|
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
|
||||||
|
|
||||||
DatabaseError = PyErr_NewException("sqlite3.DatabaseError", Error, NULL);
|
if (!(DatabaseError = PyErr_NewException("sqlite3.DatabaseError", Error, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
|
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
|
||||||
|
|
||||||
/* DatabaseError subclasses */
|
/* DatabaseError subclasses */
|
||||||
|
|
||||||
InternalError = PyErr_NewException("sqlite3.InternalError", DatabaseError, NULL);
|
if (!(InternalError = PyErr_NewException("sqlite3.InternalError", DatabaseError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "InternalError", InternalError);
|
PyDict_SetItemString(dict, "InternalError", InternalError);
|
||||||
|
|
||||||
OperationalError = PyErr_NewException("sqlite3.OperationalError", DatabaseError, NULL);
|
if (!(OperationalError = PyErr_NewException("sqlite3.OperationalError", DatabaseError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "OperationalError", OperationalError);
|
PyDict_SetItemString(dict, "OperationalError", OperationalError);
|
||||||
|
|
||||||
ProgrammingError = PyErr_NewException("sqlite3.ProgrammingError", DatabaseError, NULL);
|
if (!(ProgrammingError = PyErr_NewException("sqlite3.ProgrammingError", DatabaseError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
|
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
|
||||||
|
|
||||||
IntegrityError = PyErr_NewException("sqlite3.IntegrityError", DatabaseError,NULL);
|
if (!(IntegrityError = PyErr_NewException("sqlite3.IntegrityError", DatabaseError,NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
|
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
|
||||||
|
|
||||||
DataError = PyErr_NewException("sqlite3.DataError", DatabaseError, NULL);
|
if (!(DataError = PyErr_NewException("sqlite3.DataError", DatabaseError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "DataError", DataError);
|
PyDict_SetItemString(dict, "DataError", DataError);
|
||||||
|
|
||||||
NotSupportedError = PyErr_NewException("sqlite3.NotSupportedError", DatabaseError, NULL);
|
if (!(NotSupportedError = PyErr_NewException("sqlite3.NotSupportedError", DatabaseError, NULL))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
|
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
|
||||||
|
|
||||||
|
/* We just need "something" unique for OptimizedUnicode. It does not really
|
||||||
|
* need to be a string subclass. Just anything that can act as a special
|
||||||
|
* marker for us. So I pulled PyCell_Type out of my magic hat.
|
||||||
|
*/
|
||||||
Py_INCREF((PyObject*)&PyCell_Type);
|
Py_INCREF((PyObject*)&PyCell_Type);
|
||||||
OptimizedUnicode = (PyObject*)&PyCell_Type;
|
OptimizedUnicode = (PyObject*)&PyCell_Type;
|
||||||
PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
|
PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
|
||||||
|
|
||||||
PyDict_SetItemString(dict, "PARSE_DECLTYPES", PyInt_FromLong(PARSE_DECLTYPES));
|
if (!(tmp_obj = PyInt_FromLong(PARSE_DECLTYPES))) {
|
||||||
PyDict_SetItemString(dict, "PARSE_COLNAMES", PyInt_FromLong(PARSE_COLNAMES));
|
goto error;
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(dict, "PARSE_DECLTYPES", tmp_obj);
|
||||||
|
|
||||||
PyDict_SetItemString(dict, "version", PyString_FromString(PYSQLITE_VERSION));
|
if (!(tmp_obj = PyInt_FromLong(PARSE_COLNAMES))) {
|
||||||
PyDict_SetItemString(dict, "sqlite_version", PyString_FromString(sqlite3_libversion()));
|
goto error;
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(dict, "PARSE_COLNAMES", tmp_obj);
|
||||||
|
|
||||||
|
if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(dict, "version", tmp_obj);
|
||||||
|
|
||||||
|
if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
|
||||||
|
|
||||||
/* initialize microprotocols layer */
|
/* initialize microprotocols layer */
|
||||||
microprotocols_init(dict);
|
microprotocols_init(dict);
|
||||||
|
@ -263,10 +302,6 @@ PyMODINIT_FUNC init_sqlite3(void)
|
||||||
/* initialize the default converters */
|
/* initialize the default converters */
|
||||||
converters_init(dict);
|
converters_init(dict);
|
||||||
|
|
||||||
time_module = PyImport_ImportModule("time");
|
|
||||||
time_time = PyObject_GetAttrString(time_module, "time");
|
|
||||||
time_sleep = PyObject_GetAttrString(time_module, "sleep");
|
|
||||||
|
|
||||||
/* Original comment form _bsddb.c in the Python core. This is also still
|
/* Original comment form _bsddb.c in the Python core. This is also still
|
||||||
* needed nowadays for Python 2.3/2.4.
|
* needed nowadays for Python 2.3/2.4.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* prepare_protocol.c - the protocol for preparing values for SQLite
|
/* prepare_protocol.c - the protocol for preparing values for SQLite
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* row.c - an enhanced tuple for database rows
|
/* row.c - an enhanced tuple for database rows
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "row.h"
|
#include "row.h"
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
void row_dealloc(Row* self)
|
void row_dealloc(Row* self)
|
||||||
{
|
{
|
||||||
|
@ -78,9 +79,12 @@ PyObject* row_subscript(Row* self, PyObject* idx)
|
||||||
if (PyInt_Check(idx)) {
|
if (PyInt_Check(idx)) {
|
||||||
_idx = PyInt_AsLong(idx);
|
_idx = PyInt_AsLong(idx);
|
||||||
item = PyTuple_GetItem(self->data, _idx);
|
item = PyTuple_GetItem(self->data, _idx);
|
||||||
if (item) {
|
Py_XINCREF(item);
|
||||||
Py_INCREF(item);
|
return item;
|
||||||
}
|
} else if (PyLong_Check(idx)) {
|
||||||
|
_idx = PyLong_AsLong(idx);
|
||||||
|
item = PyTuple_GetItem(self->data, _idx);
|
||||||
|
Py_XINCREF(item);
|
||||||
return item;
|
return item;
|
||||||
} else if (PyString_Check(idx)) {
|
} else if (PyString_Check(idx)) {
|
||||||
key = PyString_AsString(idx);
|
key = PyString_AsString(idx);
|
||||||
|
@ -89,6 +93,9 @@ PyObject* row_subscript(Row* self, PyObject* idx)
|
||||||
|
|
||||||
for (i = 0; i < nitems; i++) {
|
for (i = 0; i < nitems; i++) {
|
||||||
compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
|
compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
|
||||||
|
if (!compare_key) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
p1 = key;
|
p1 = key;
|
||||||
p2 = compare_key;
|
p2 = compare_key;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* sqlitecompat.h - compatibility macros
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 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.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PYSQLITE_COMPAT_H
|
||||||
|
#define PYSQLITE_COMPAT_H
|
||||||
|
|
||||||
|
/* define Py_ssize_t for pre-2.5 versions of Python */
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX < 0x02050000
|
||||||
|
typedef int Py_ssize_t;
|
||||||
|
typedef int (*lenfunc)(PyObject*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "microprotocols.h"
|
#include "microprotocols.h"
|
||||||
#include "prepare_protocol.h"
|
#include "prepare_protocol.h"
|
||||||
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
int check_remaining_sql(const char* tail);
|
int check_remaining_sql(const char* tail);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* util.c - various utility functions
|
/* util.c - various utility functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -24,30 +24,6 @@
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* it's not so trivial to write a portable sleep in C. For now, the simplest
|
|
||||||
* solution is to just use Python's sleep().
|
|
||||||
*/
|
|
||||||
void pysqlite_sleep(double seconds)
|
|
||||||
{
|
|
||||||
PyObject* ret;
|
|
||||||
|
|
||||||
ret = PyObject_CallFunction(time_sleep, "d", seconds);
|
|
||||||
Py_DECREF(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
double pysqlite_time(void)
|
|
||||||
{
|
|
||||||
PyObject* ret;
|
|
||||||
double time;
|
|
||||||
|
|
||||||
ret = PyObject_CallFunction(time_time, "");
|
|
||||||
time = PyFloat_AsDouble(ret);
|
|
||||||
Py_DECREF(ret);
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
|
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -75,63 +51,35 @@ int _seterror(sqlite3* db)
|
||||||
case SQLITE_OK:
|
case SQLITE_OK:
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
break;
|
break;
|
||||||
case SQLITE_ERROR:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_INTERNAL:
|
case SQLITE_INTERNAL:
|
||||||
|
case SQLITE_NOTFOUND:
|
||||||
PyErr_SetString(InternalError, sqlite3_errmsg(db));
|
PyErr_SetString(InternalError, sqlite3_errmsg(db));
|
||||||
break;
|
break;
|
||||||
case SQLITE_PERM:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_ABORT:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_BUSY:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_LOCKED:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_NOMEM:
|
case SQLITE_NOMEM:
|
||||||
(void)PyErr_NoMemory();
|
(void)PyErr_NoMemory();
|
||||||
break;
|
break;
|
||||||
|
case SQLITE_ERROR:
|
||||||
|
case SQLITE_PERM:
|
||||||
|
case SQLITE_ABORT:
|
||||||
|
case SQLITE_BUSY:
|
||||||
|
case SQLITE_LOCKED:
|
||||||
case SQLITE_READONLY:
|
case SQLITE_READONLY:
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_INTERRUPT:
|
case SQLITE_INTERRUPT:
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_IOERR:
|
case SQLITE_IOERR:
|
||||||
|
case SQLITE_FULL:
|
||||||
|
case SQLITE_CANTOPEN:
|
||||||
|
case SQLITE_PROTOCOL:
|
||||||
|
case SQLITE_EMPTY:
|
||||||
|
case SQLITE_SCHEMA:
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
||||||
break;
|
break;
|
||||||
case SQLITE_CORRUPT:
|
case SQLITE_CORRUPT:
|
||||||
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
|
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
|
||||||
break;
|
break;
|
||||||
case SQLITE_NOTFOUND:
|
|
||||||
PyErr_SetString(InternalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_FULL:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_CANTOPEN:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_PROTOCOL:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_EMPTY:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_SCHEMA:
|
|
||||||
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_TOOBIG:
|
case SQLITE_TOOBIG:
|
||||||
PyErr_SetString(DataError, sqlite3_errmsg(db));
|
PyErr_SetString(DataError, sqlite3_errmsg(db));
|
||||||
break;
|
break;
|
||||||
case SQLITE_CONSTRAINT:
|
case SQLITE_CONSTRAINT:
|
||||||
PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
|
|
||||||
break;
|
|
||||||
case SQLITE_MISMATCH:
|
case SQLITE_MISMATCH:
|
||||||
PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
|
PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
|
||||||
break;
|
break;
|
||||||
|
@ -140,6 +88,7 @@ int _seterror(sqlite3* db)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
|
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorcode;
|
return errorcode;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* util.h - various utility functions
|
/* util.h - various utility functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -28,8 +28,6 @@
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
void pysqlite_sleep(double seconds);
|
|
||||||
|
|
||||||
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
|
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -752,7 +752,7 @@ class PyBuildExt(build_ext):
|
||||||
'_sqlite/statement.c',
|
'_sqlite/statement.c',
|
||||||
'_sqlite/util.c', ]
|
'_sqlite/util.c', ]
|
||||||
|
|
||||||
PYSQLITE_VERSION = "2.1.3"
|
PYSQLITE_VERSION = "2.2.0"
|
||||||
sqlite_defines = []
|
sqlite_defines = []
|
||||||
if sys.platform != "win32":
|
if sys.platform != "win32":
|
||||||
sqlite_defines.append(('PYSQLITE_VERSION',
|
sqlite_defines.append(('PYSQLITE_VERSION',
|
||||||
|
|
Loading…
Reference in New Issue