Skip to content

Commit 3e99c0a

Browse files
committed
Updated the sqlite3 module to the external pysqlite 2.2.2 version.
1 parent 5ef9d9f commit 3e99c0a

File tree

22 files changed

+311
-314
lines changed

22 files changed

+311
-314
lines changed

Lib/sqlite3/dbapi2.py

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,63 +22,67 @@
2222
# 3. This notice may not be removed or altered from any source distribution.
2323

2424
import datetime
25+
import time
26+
27+
from _sqlite3 import *
2528

2629
paramstyle = "qmark"
2730

2831
threadsafety = 1
2932

3033
apilevel = "2.0"
3134

32-
from _sqlite3 import *
33-
34-
import datetime, time
35-
3635
Date = datetime.date
3736

3837
Time = datetime.time
3938

4039
Timestamp = datetime.datetime
4140

4241
def DateFromTicks(ticks):
43-
return apply(Date,time.localtime(ticks)[:3])
42+
return apply(Date, time.localtime(ticks)[:3])
4443

4544
def TimeFromTicks(ticks):
46-
return apply(Time,time.localtime(ticks)[3:6])
45+
return apply(Time, time.localtime(ticks)[3:6])
4746

4847
def TimestampFromTicks(ticks):
49-
return apply(Timestamp,time.localtime(ticks)[:6])
48+
return apply(Timestamp, time.localtime(ticks)[:6])
5049

51-
_major, _minor, _micro = version.split(".")
52-
version_info = (int(_major), int(_minor), _micro)
53-
_major, _minor, _micro = sqlite_version.split(".")
54-
sqlite_version_info = (int(_major), int(_minor), _micro)
50+
version_info = tuple([int(x) for x in version.split(".")])
51+
sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")])
5552

5653
Binary = buffer
5754

58-
def adapt_date(val):
59-
return val.isoformat()
55+
def register_adapters_and_converters():
56+
def adapt_date(val):
57+
return val.isoformat()
58+
59+
def adapt_datetime(val):
60+
return val.isoformat(" ")
61+
62+
def convert_date(val):
63+
return datetime.date(*map(int, val.split("-")))
64+
65+
def convert_timestamp(val):
66+
datepart, timepart = val.split(" ")
67+
year, month, day = map(int, datepart.split("-"))
68+
timepart_full = timepart.split(".")
69+
hours, minutes, seconds = map(int, timepart_full[0].split(":"))
70+
if len(timepart_full) == 2:
71+
microseconds = int(float("0." + timepart_full[1]) * 1000000)
72+
else:
73+
microseconds = 0
6074

61-
def adapt_datetime(val):
62-
return val.isoformat(" ")
75+
val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
76+
return val
6377

64-
def convert_date(val):
65-
return datetime.date(*map(int, val.split("-")))
6678

67-
def convert_timestamp(val):
68-
datepart, timepart = val.split(" ")
69-
year, month, day = map(int, datepart.split("-"))
70-
timepart_full = timepart.split(".")
71-
hours, minutes, seconds = map(int, timepart_full[0].split(":"))
72-
if len(timepart_full) == 2:
73-
microseconds = int(float("0." + timepart_full[1]) * 1000000)
74-
else:
75-
microseconds = 0
79+
register_adapter(datetime.date, adapt_date)
80+
register_adapter(datetime.datetime, adapt_datetime)
81+
register_converter("date", convert_date)
82+
register_converter("timestamp", convert_timestamp)
7683

77-
val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
78-
return val
84+
register_adapters_and_converters()
7985

86+
# Clean up namespace
8087

81-
register_adapter(datetime.date, adapt_date)
82-
register_adapter(datetime.datetime, adapt_datetime)
83-
register_converter("date", convert_date)
84-
register_converter("timestamp", convert_timestamp)
88+
del(register_adapters_and_converters)

Lib/sqlite3/test/hooks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
# 3. This notice may not be removed or altered from any source distribution.
2323

2424
import os, unittest
25-
import pysqlite2.dbapi2 as sqlite
25+
import sqlite3 as sqlite
2626

2727
class CollationTests(unittest.TestCase):
2828
def setUp(self):
@@ -72,7 +72,7 @@ def mycoll(x, y):
7272
result = con.execute(sql).fetchall()
7373
self.fail("should have raised an OperationalError")
7474
except sqlite.OperationalError, e:
75-
self.failUnlessEqual(e.args[0], "no such collation sequence: mycoll")
75+
self.failUnlessEqual(e.args[0].lower(), "no such collation sequence: mycoll")
7676

7777
def CheckCollationRegisterTwice(self):
7878
"""

Lib/sqlite3/test/regression.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
# 3. This notice may not be removed or altered from any source distribution.
2323

2424
import unittest
25-
import pysqlite2.dbapi2 as sqlite
25+
import sqlite3 as sqlite
2626

2727
class RegressionTests(unittest.TestCase):
2828
def setUp(self):
@@ -36,6 +36,31 @@ def CheckPragmaUserVersion(self):
3636
cur = self.con.cursor()
3737
cur.execute("pragma user_version")
3838

39+
def CheckPragmaSchemaVersion(self):
40+
# This still crashed pysqlite <= 2.2.1
41+
con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
42+
try:
43+
cur = self.con.cursor()
44+
cur.execute("pragma schema_version")
45+
finally:
46+
cur.close()
47+
con.close()
48+
49+
def CheckStatementReset(self):
50+
# pysqlite 2.1.0 to 2.2.0 have the problem that not all statements are
51+
# reset before a rollback, but only those that are still in the
52+
# statement cache. The others are not accessible from the connection object.
53+
con = sqlite.connect(":memory:", cached_statements=5)
54+
cursors = [con.cursor() for x in xrange(5)]
55+
cursors[0].execute("create table test(x)")
56+
for i in range(10):
57+
cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in xrange(10)])
58+
59+
for i in range(5):
60+
cursors[i].execute(" " * i + "select x from test")
61+
62+
con.rollback()
63+
3964
def suite():
4065
regression_suite = unittest.makeSuite(RegressionTests, "Check")
4166
return unittest.TestSuite((regression_suite,))

Lib/sqlite3/test/userfunctions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ def setUp(self):
134134
def tearDown(self):
135135
self.con.close()
136136

137+
def CheckFuncErrorOnCreate(self):
138+
try:
139+
self.con.create_function("bla", -100, lambda x: 2*x)
140+
self.fail("should have raised an OperationalError")
141+
except sqlite.OperationalError:
142+
pass
143+
137144
def CheckFuncRefCount(self):
138145
def getfunc():
139146
def f():
@@ -251,6 +258,13 @@ def tearDown(self):
251258
#self.con.close()
252259
pass
253260

261+
def CheckAggrErrorOnCreate(self):
262+
try:
263+
self.con.create_function("bla", -100, AggrSum)
264+
self.fail("should have raised an OperationalError")
265+
except sqlite.OperationalError:
266+
pass
267+
254268
def CheckAggrNoStep(self):
255269
cur = self.con.cursor()
256270
cur.execute("select nostep(t) from test")

Lib/test/test_sqlite.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
except ImportError:
77
raise TestSkipped('no sqlite available')
88
from sqlite3.test import (dbapi, types, userfunctions,
9-
factory, transactions)
9+
factory, transactions, hooks, regression)
1010

1111
def test_main():
1212
run_unittest(dbapi.suite(), types.suite(), userfunctions.suite(),
13-
factory.suite(), transactions.suite())
13+
factory.suite(), transactions.suite(), hooks.suite(),
14+
regression.suite())
1415

1516
if __name__ == "__main__":
1617
test_main()

Modules/_sqlite/adapters.c

Lines changed: 0 additions & 40 deletions
This file was deleted.

Modules/_sqlite/adapters.h

Lines changed: 0 additions & 33 deletions
This file was deleted.

Modules/_sqlite/cache.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include "cache.h"
25+
#include <limits.h>
2526

2627
/* only used internally */
2728
Node* new_node(PyObject* key, PyObject* data)
@@ -60,11 +61,11 @@ int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
6061

6162
self->factory = NULL;
6263

63-
if (!PyArg_ParseTuple(args, "O|i", &factory, &size))
64-
{
65-
return -1;
64+
if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
65+
return -1;
6666
}
6767

68+
/* minimum cache size is 5 entries */
6869
if (size < 5) {
6970
size = 5;
7071
}
@@ -95,6 +96,7 @@ void cache_dealloc(Cache* self)
9596
return;
9697
}
9798

99+
/* iterate over all nodes and deallocate them */
98100
node = self->first;
99101
while (node) {
100102
delete_node = node;
@@ -119,7 +121,14 @@ PyObject* cache_get(Cache* self, PyObject* args)
119121

120122
node = (Node*)PyDict_GetItem(self->mapping, key);
121123
if (node) {
122-
node->count++;
124+
/* an entry for this key already exists in the cache */
125+
126+
/* increase usage counter of the node found */
127+
if (node->count < LONG_MAX) {
128+
node->count++;
129+
}
130+
131+
/* if necessary, reorder entries in the cache by swapping positions */
123132
if (node->prev && node->count > node->prev->count) {
124133
ptr = node->prev;
125134

@@ -149,6 +158,10 @@ PyObject* cache_get(Cache* self, PyObject* args)
149158
ptr->prev = node;
150159
}
151160
} else {
161+
/* There is no entry for this key in the cache, yet. We'll insert a new
162+
* entry in the cache, and make space if necessary by throwing the
163+
* least used item out of the cache. */
164+
152165
if (PyDict_Size(self->mapping) == self->size) {
153166
if (self->last) {
154167
node = self->last;
@@ -253,7 +266,7 @@ PyObject* cache_display(Cache* self, PyObject* args)
253266

254267
static PyMethodDef cache_methods[] = {
255268
{"get", (PyCFunction)cache_get, METH_O,
256-
PyDoc_STR("Gets an entry from the cache.")},
269+
PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
257270
{"display", (PyCFunction)cache_display, METH_NOARGS,
258271
PyDoc_STR("For debugging only.")},
259272
{NULL, NULL}

Modules/_sqlite/cache.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* cache.h - definitions for the LRU cache
22
*
3-
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
3+
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
44
*
55
* This file is part of pysqlite.
66
*
@@ -25,6 +25,10 @@
2525
#define PYSQLITE_CACHE_H
2626
#include "Python.h"
2727

28+
/* The LRU cache is implemented as a combination of a doubly-linked with a
29+
* dictionary. The list items are of type 'Node' and the dictionary has the
30+
* nodes as values. */
31+
2832
typedef struct _Node
2933
{
3034
PyObject_HEAD
@@ -39,10 +43,18 @@ typedef struct
3943
{
4044
PyObject_HEAD
4145
int size;
46+
47+
/* a dictionary mapping keys to Node entries */
4248
PyObject* mapping;
49+
50+
/* the factory callable */
4351
PyObject* factory;
52+
4453
Node* first;
4554
Node* last;
55+
56+
/* if set, decrement the factory function when the Cache is deallocated.
57+
* this is almost always desirable, but not in the pysqlite context */
4658
int decref_factory;
4759
} Cache;
4860

0 commit comments

Comments
 (0)