Skip to content

Commit 63c6d27

Browse files
author
jef
committedJan 10, 2011
add 'internal' pyspatialite
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15015 c8812cc2-4d05-0410-92ff-de0c093fc19c

25 files changed

+5636
-0
lines changed
 

‎python/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
SUBDIRS(plugins)
22

33
IF (WITH_INTERNAL_SPATIALITE)
4+
SUBDIRS(pyspatialite)
5+
46
INCLUDE_DIRECTORIES(
57
../src/core/spatialite/headers
68
../src/core/spatialite/headers/spatialite

‎python/pyspatialite/CMakeLists.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
INCLUDE_DIRECTORIES(
2+
../../src/core/spatialite/headers
3+
../../src/core/spatialite/headers/spatialite
4+
5+
${PYTHON_INCLUDE_PATH}
6+
${GEOS_INCLUDE_DIR}
7+
${PROJ_INCLUDE_DIR}
8+
)
9+
10+
SET(PYSPATIALITE_SRC
11+
src/cache.c
12+
src/connection.c
13+
src/cursor.c
14+
src/microprotocols.c
15+
src/module.c
16+
src/prepare_protocol.c
17+
src/row.c
18+
src/statement.c
19+
src/util.c
20+
)
21+
22+
ADD_DEFINITIONS(-DMODULE_NAME=\\\"spatialite.dbapi2\\\")
23+
24+
IF (CYGWIN OR APPLE)
25+
ADD_LIBRARY(pyspatialite MODULE ${PYSPATIALITE_SRC})
26+
ELSE (CYGWIN OR APPLE)
27+
ADD_LIBRARY(pyspatialite SHARED ${PYSPATIALITE_SRC})
28+
ENDIF (CYGWIN OR APPLE)
29+
30+
IF (NOT APPLE)
31+
TARGET_LINK_LIBRARIES(pyspatialite ${PYTHON_LIBRARY})
32+
ENDIF (NOT APPLE)
33+
34+
TARGET_LINK_LIBRARIES(pyspatialite ${EXTRA_LINK_LIBRARIES})
35+
36+
IF (APPLE)
37+
SET_TARGET_PROPERTIES(pyspatialite PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
38+
ENDIF (APPLE)
39+
40+
SET_TARGET_PROPERTIES(pyspatialite PROPERTIES PREFIX "" OUTPUT_NAME _spatialite)
41+
42+
IF (WIN32)
43+
SET_TARGET_PROPERTIES(pyspatialite PROPERTIES SUFFIX ".pyd")
44+
ENDIF (WIN32)
45+
46+
INSTALL(TARGETS pyspatialite DESTINATION "${PYTHON_SITE_PACKAGES_DIR}/pyspatialite")
47+
INSTALL(FILES
48+
lib/__init__.py
49+
lib/dbapi2.py
50+
lib/dump.py
51+
DESTINATION "${PYTHON_SITE_PACKAGES_DIR}/pyspatialite")

‎python/pyspatialite/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2004-2007 Gerhard Häring
2+
3+
This software is provided 'as-is', without any express or implied warranty. In
4+
no event will the authors be held liable for any damages arising from the use
5+
of this software.
6+
7+
Permission is granted to anyone to use this software for any purpose,
8+
including commercial applications, and to alter it and redistribute it freely,
9+
subject to the following restrictions:
10+
11+
1. The origin of this software must not be misrepresented; you must not
12+
claim that you wrote the original software. If you use this software in
13+
a product, an acknowledgment in the product documentation would be
14+
appreciated but is not required.
15+
16+
2. Altered source versions must be plainly marked as such, and must not be
17+
misrepresented as being the original software.
18+
19+
3. This notice may not be removed or altered from any source distribution.

‎python/pyspatialite/lib/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#-*- coding: ISO-8859-1 -*-
2+
# pysqlite2/__init__.py: the pysqlite2 package.
3+
#
4+
# Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
5+
#
6+
# This file is part of pysqlite.
7+
#
8+
# This software is provided 'as-is', without any express or implied
9+
# warranty. In no event will the authors be held liable for any damages
10+
# arising from the use of this software.
11+
#
12+
# Permission is granted to anyone to use this software for any purpose,
13+
# including commercial applications, and to alter it and redistribute it
14+
# freely, subject to the following restrictions:
15+
#
16+
# 1. The origin of this software must not be misrepresented; you must not
17+
# claim that you wrote the original software. If you use this software
18+
# in a product, an acknowledgment in the product documentation would be
19+
# appreciated but is not required.
20+
# 2. Altered source versions must be plainly marked as such, and must not be
21+
# misrepresented as being the original software.
22+
# 3. This notice may not be removed or altered from any source distribution.

‎python/pyspatialite/lib/dbapi2.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#-*- coding: ISO-8859-1 -*-
2+
# pyspatialite/dbapi2.py: the DB-API 2.0 interface
3+
#
4+
# Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
5+
#
6+
# This file is part of pysqlite.
7+
#
8+
# This software is provided 'as-is', without any express or implied
9+
# warranty. In no event will the authors be held liable for any damages
10+
# arising from the use of this software.
11+
#
12+
# Permission is granted to anyone to use this software for any purpose,
13+
# including commercial applications, and to alter it and redistribute it
14+
# freely, subject to the following restrictions:
15+
#
16+
# 1. The origin of this software must not be misrepresented; you must not
17+
# claim that you wrote the original software. If you use this software
18+
# in a product, an acknowledgment in the product documentation would be
19+
# appreciated but is not required.
20+
# 2. Altered source versions must be plainly marked as such, and must not be
21+
# misrepresented as being the original software.
22+
# 3. This notice may not be removed or altered from any source distribution.
23+
24+
import datetime
25+
import time
26+
27+
from pyspatialite._spatialite import *
28+
29+
paramstyle = "qmark"
30+
31+
threadsafety = 1
32+
33+
apilevel = "2.0"
34+
35+
Date = datetime.date
36+
37+
Time = datetime.time
38+
39+
Timestamp = datetime.datetime
40+
41+
def DateFromTicks(ticks):
42+
return Date(*time.localtime(ticks)[:3])
43+
44+
def TimeFromTicks(ticks):
45+
return Time(*time.localtime(ticks)[3:6])
46+
47+
def TimestampFromTicks(ticks):
48+
return Timestamp(*time.localtime(ticks)[:6])
49+
50+
version_info = tuple([int(x) for x in version.split(".")])
51+
sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")])
52+
53+
Binary = buffer
54+
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(timepart_full[1])
72+
else:
73+
microseconds = 0
74+
75+
val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
76+
return val
77+
78+
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)
83+
84+
register_adapters_and_converters()
85+
86+
# Clean up namespace
87+
88+
del(register_adapters_and_converters)

‎python/pyspatialite/lib/dump.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Mimic the sqlite3 console shell's .dump command
2+
# Author: Paul Kippes <kippesp@gmail.com>
3+
4+
def _iterdump(connection):
5+
"""
6+
Returns an iterator to the dump of the database in an SQL text format.
7+
8+
Used to produce an SQL dump of the database. Useful to save an in-memory
9+
database for later restoration. This function should not be called
10+
directly but instead called from the Connection method, iterdump().
11+
"""
12+
13+
cu = connection.cursor()
14+
yield('BEGIN TRANSACTION;')
15+
16+
# sqlite_master table contains the SQL CREATE statements for the database.
17+
q = """
18+
SELECT name, type, sql
19+
FROM sqlite_master
20+
WHERE sql NOT NULL AND
21+
type == 'table'
22+
"""
23+
schema_res = cu.execute(q)
24+
for table_name, type, sql in schema_res.fetchall():
25+
if table_name == 'sqlite_sequence':
26+
yield('DELETE FROM sqlite_sequence;')
27+
elif table_name == 'sqlite_stat1':
28+
yield('ANALYZE sqlite_master;')
29+
elif table_name.startswith('sqlite_'):
30+
continue
31+
# NOTE: Virtual table support not implemented
32+
#elif sql.startswith('CREATE VIRTUAL TABLE'):
33+
# qtable = table_name.replace("'", "''")
34+
# yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\
35+
# "VALUES('table','%s','%s',0,'%s');" %
36+
# qtable,
37+
# qtable,
38+
# sql.replace("''"))
39+
else:
40+
yield('%s;' % sql)
41+
42+
# Build the insert statement for each row of the current table
43+
res = cu.execute("PRAGMA table_info('%s')" % table_name)
44+
column_names = [str(table_info[1]) for table_info in res.fetchall()]
45+
q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES("
46+
q += ",".join(["'||quote(" + col + ")||'" for col in column_names])
47+
q += ")' FROM '%(tbl_name)s'"
48+
query_res = cu.execute(q % {'tbl_name': table_name})
49+
for row in query_res:
50+
yield("%s;" % row[0])
51+
52+
# Now when the type is 'index', 'trigger', or 'view'
53+
q = """
54+
SELECT name, type, sql
55+
FROM sqlite_master
56+
WHERE sql NOT NULL AND
57+
type IN ('index', 'trigger', 'view')
58+
"""
59+
schema_res = cu.execute(q)
60+
for name, type, sql in schema_res.fetchall():
61+
yield('%s;' % sql)
62+
63+
yield('COMMIT;')

‎python/pyspatialite/src/cache.c

Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
/* cache .c - a LRU cache
2+
*
3+
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#include "sqlitecompat.h"
25+
#include "cache.h"
26+
#include <limits.h>
27+
28+
/* only used internally */
29+
pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data)
30+
{
31+
pysqlite_Node* node;
32+
33+
node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0));
34+
if (!node) {
35+
return NULL;
36+
}
37+
38+
Py_INCREF(key);
39+
node->key = key;
40+
41+
Py_INCREF(data);
42+
node->data = data;
43+
44+
node->prev = NULL;
45+
node->next = NULL;
46+
47+
return node;
48+
}
49+
50+
void pysqlite_node_dealloc(pysqlite_Node* self)
51+
{
52+
Py_DECREF(self->key);
53+
Py_DECREF(self->data);
54+
55+
Py_TYPE(self)->tp_free((PyObject*)self);
56+
}
57+
58+
int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs)
59+
{
60+
PyObject* factory;
61+
int size = 10;
62+
63+
self->factory = NULL;
64+
65+
if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
66+
return -1;
67+
}
68+
69+
/* minimum cache size is 5 entries */
70+
if (size < 5) {
71+
size = 5;
72+
}
73+
self->size = size;
74+
self->first = NULL;
75+
self->last = NULL;
76+
77+
self->mapping = PyDict_New();
78+
if (!self->mapping) {
79+
return -1;
80+
}
81+
82+
Py_INCREF(factory);
83+
self->factory = factory;
84+
85+
self->decref_factory = 1;
86+
87+
return 0;
88+
}
89+
90+
void pysqlite_cache_dealloc(pysqlite_Cache* self)
91+
{
92+
pysqlite_Node* node;
93+
pysqlite_Node* delete_node;
94+
95+
if (!self->factory) {
96+
/* constructor failed, just get out of here */
97+
return;
98+
}
99+
100+
/* iterate over all nodes and deallocate them */
101+
node = self->first;
102+
while (node) {
103+
delete_node = node;
104+
node = node->next;
105+
Py_DECREF(delete_node);
106+
}
107+
108+
if (self->decref_factory) {
109+
Py_DECREF(self->factory);
110+
}
111+
Py_DECREF(self->mapping);
112+
113+
Py_TYPE(self)->tp_free((PyObject*)self);
114+
}
115+
116+
PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args)
117+
{
118+
PyObject* key = args;
119+
pysqlite_Node* node;
120+
pysqlite_Node* ptr;
121+
PyObject* data;
122+
123+
node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key);
124+
if (node) {
125+
/* an entry for this key already exists in the cache */
126+
127+
/* increase usage counter of the node found */
128+
if (node->count < LONG_MAX) {
129+
node->count++;
130+
}
131+
132+
/* if necessary, reorder entries in the cache by swapping positions */
133+
if (node->prev && node->count > node->prev->count) {
134+
ptr = node->prev;
135+
136+
while (ptr->prev && node->count > ptr->prev->count) {
137+
ptr = ptr->prev;
138+
}
139+
140+
if (node->next) {
141+
node->next->prev = node->prev;
142+
} else {
143+
self->last = node->prev;
144+
}
145+
if (node->prev) {
146+
node->prev->next = node->next;
147+
}
148+
if (ptr->prev) {
149+
ptr->prev->next = node;
150+
} else {
151+
self->first = node;
152+
}
153+
154+
node->next = ptr;
155+
node->prev = ptr->prev;
156+
if (!node->prev) {
157+
self->first = node;
158+
}
159+
ptr->prev = node;
160+
}
161+
} else {
162+
/* There is no entry for this key in the cache, yet. We'll insert a new
163+
* entry in the cache, and make space if necessary by throwing the
164+
* least used item out of the cache. */
165+
166+
if (PyDict_Size(self->mapping) == self->size) {
167+
if (self->last) {
168+
node = self->last;
169+
170+
if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
171+
return NULL;
172+
}
173+
174+
if (node->prev) {
175+
node->prev->next = NULL;
176+
}
177+
self->last = node->prev;
178+
node->prev = NULL;
179+
180+
Py_DECREF(node);
181+
}
182+
}
183+
184+
data = PyObject_CallFunction(self->factory, "O", key);
185+
186+
if (!data) {
187+
return NULL;
188+
}
189+
190+
node = pysqlite_new_node(key, data);
191+
if (!node) {
192+
return NULL;
193+
}
194+
node->prev = self->last;
195+
196+
Py_DECREF(data);
197+
198+
if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
199+
Py_DECREF(node);
200+
return NULL;
201+
}
202+
203+
if (self->last) {
204+
self->last->next = node;
205+
} else {
206+
self->first = node;
207+
}
208+
self->last = node;
209+
}
210+
211+
Py_INCREF(node->data);
212+
return node->data;
213+
}
214+
215+
PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args)
216+
{
217+
pysqlite_Node* ptr;
218+
PyObject* prevkey;
219+
PyObject* nextkey;
220+
PyObject* fmt_args;
221+
PyObject* template;
222+
PyObject* display_str;
223+
224+
ptr = self->first;
225+
226+
while (ptr) {
227+
if (ptr->prev) {
228+
prevkey = ptr->prev->key;
229+
} else {
230+
prevkey = Py_None;
231+
}
232+
Py_INCREF(prevkey);
233+
234+
if (ptr->next) {
235+
nextkey = ptr->next->key;
236+
} else {
237+
nextkey = Py_None;
238+
}
239+
Py_INCREF(nextkey);
240+
241+
fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
242+
if (!fmt_args) {
243+
return NULL;
244+
}
245+
template = PyString_FromString("%s <- %s ->%s\n");
246+
if (!template) {
247+
Py_DECREF(fmt_args);
248+
return NULL;
249+
}
250+
display_str = PyString_Format(template, fmt_args);
251+
Py_DECREF(template);
252+
Py_DECREF(fmt_args);
253+
if (!display_str) {
254+
return NULL;
255+
}
256+
PyObject_Print(display_str, stdout, Py_PRINT_RAW);
257+
Py_DECREF(display_str);
258+
259+
Py_DECREF(prevkey);
260+
Py_DECREF(nextkey);
261+
262+
ptr = ptr->next;
263+
}
264+
265+
Py_INCREF(Py_None);
266+
return Py_None;
267+
}
268+
269+
static PyMethodDef cache_methods[] = {
270+
{"get", (PyCFunction)pysqlite_cache_get, METH_O,
271+
PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
272+
{"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS,
273+
PyDoc_STR("For debugging only.")},
274+
{NULL, NULL}
275+
};
276+
277+
PyTypeObject pysqlite_NodeType = {
278+
PyVarObject_HEAD_INIT(NULL, 0)
279+
MODULE_NAME "Node", /* tp_name */
280+
sizeof(pysqlite_Node), /* tp_basicsize */
281+
0, /* tp_itemsize */
282+
(destructor)pysqlite_node_dealloc, /* tp_dealloc */
283+
0, /* tp_print */
284+
0, /* tp_getattr */
285+
0, /* tp_setattr */
286+
0, /* tp_compare */
287+
0, /* tp_repr */
288+
0, /* tp_as_number */
289+
0, /* tp_as_sequence */
290+
0, /* tp_as_mapping */
291+
0, /* tp_hash */
292+
0, /* tp_call */
293+
0, /* tp_str */
294+
0, /* tp_getattro */
295+
0, /* tp_setattro */
296+
0, /* tp_as_buffer */
297+
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
298+
0, /* tp_doc */
299+
0, /* tp_traverse */
300+
0, /* tp_clear */
301+
0, /* tp_richcompare */
302+
0, /* tp_weaklistoffset */
303+
0, /* tp_iter */
304+
0, /* tp_iternext */
305+
0, /* tp_methods */
306+
0, /* tp_members */
307+
0, /* tp_getset */
308+
0, /* tp_base */
309+
0, /* tp_dict */
310+
0, /* tp_descr_get */
311+
0, /* tp_descr_set */
312+
0, /* tp_dictoffset */
313+
(initproc)0, /* tp_init */
314+
0, /* tp_alloc */
315+
0, /* tp_new */
316+
0 /* tp_free */
317+
};
318+
319+
PyTypeObject pysqlite_CacheType = {
320+
PyVarObject_HEAD_INIT(NULL, 0)
321+
MODULE_NAME ".Cache", /* tp_name */
322+
sizeof(pysqlite_Cache), /* tp_basicsize */
323+
0, /* tp_itemsize */
324+
(destructor)pysqlite_cache_dealloc, /* tp_dealloc */
325+
0, /* tp_print */
326+
0, /* tp_getattr */
327+
0, /* tp_setattr */
328+
0, /* tp_compare */
329+
0, /* tp_repr */
330+
0, /* tp_as_number */
331+
0, /* tp_as_sequence */
332+
0, /* tp_as_mapping */
333+
0, /* tp_hash */
334+
0, /* tp_call */
335+
0, /* tp_str */
336+
0, /* tp_getattro */
337+
0, /* tp_setattro */
338+
0, /* tp_as_buffer */
339+
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
340+
0, /* tp_doc */
341+
0, /* tp_traverse */
342+
0, /* tp_clear */
343+
0, /* tp_richcompare */
344+
0, /* tp_weaklistoffset */
345+
0, /* tp_iter */
346+
0, /* tp_iternext */
347+
cache_methods, /* tp_methods */
348+
0, /* tp_members */
349+
0, /* tp_getset */
350+
0, /* tp_base */
351+
0, /* tp_dict */
352+
0, /* tp_descr_get */
353+
0, /* tp_descr_set */
354+
0, /* tp_dictoffset */
355+
(initproc)pysqlite_cache_init, /* tp_init */
356+
0, /* tp_alloc */
357+
0, /* tp_new */
358+
0 /* tp_free */
359+
};
360+
361+
extern int pysqlite_cache_setup_types(void)
362+
{
363+
int rc;
364+
365+
pysqlite_NodeType.tp_new = PyType_GenericNew;
366+
pysqlite_CacheType.tp_new = PyType_GenericNew;
367+
368+
rc = PyType_Ready(&pysqlite_NodeType);
369+
if (rc < 0) {
370+
return rc;
371+
}
372+
373+
rc = PyType_Ready(&pysqlite_CacheType);
374+
return rc;
375+
}

‎python/pyspatialite/src/cache.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* cache.h - definitions for the LRU cache
2+
*
3+
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_CACHE_H
25+
#define PYSQLITE_CACHE_H
26+
#include "Python.h"
27+
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+
32+
typedef struct _pysqlite_Node
33+
{
34+
PyObject_HEAD
35+
PyObject* key;
36+
PyObject* data;
37+
long count;
38+
struct _pysqlite_Node* prev;
39+
struct _pysqlite_Node* next;
40+
} pysqlite_Node;
41+
42+
typedef struct
43+
{
44+
PyObject_HEAD
45+
int size;
46+
47+
/* a dictionary mapping keys to Node entries */
48+
PyObject* mapping;
49+
50+
/* the factory callable */
51+
PyObject* factory;
52+
53+
pysqlite_Node* first;
54+
pysqlite_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 */
58+
int decref_factory;
59+
} pysqlite_Cache;
60+
61+
extern PyTypeObject pysqlite_NodeType;
62+
extern PyTypeObject pysqlite_CacheType;
63+
64+
int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs);
65+
void pysqlite_node_dealloc(pysqlite_Node* self);
66+
67+
int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs);
68+
void pysqlite_cache_dealloc(pysqlite_Cache* self);
69+
PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args);
70+
71+
int pysqlite_cache_setup_types(void);
72+
73+
#endif

‎python/pyspatialite/src/connection.c

Lines changed: 1661 additions & 0 deletions
Large diffs are not rendered by default.

‎python/pyspatialite/src/connection.h

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* connection.h - definitions for the connection type
2+
*
3+
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_CONNECTION_H
25+
#define PYSQLITE_CONNECTION_H
26+
#include "Python.h"
27+
#include "pythread.h"
28+
#include "structmember.h"
29+
30+
#include "cache.h"
31+
#include "module.h"
32+
33+
#include "sqlite3.h"
34+
#include "spatialite.h"
35+
36+
// int spatialite_init(int verbose);
37+
38+
typedef struct
39+
{
40+
PyObject_HEAD
41+
sqlite3* db;
42+
43+
/* 1 if we are currently within a transaction, i. e. if a BEGIN has been
44+
* issued */
45+
int inTransaction;
46+
47+
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
48+
* bitwise combination thereof makes sense */
49+
int detect_types;
50+
51+
/* the timeout value in seconds for database locks */
52+
double timeout;
53+
54+
/* for internal use in the timeout handler: when did the timeout handler
55+
* first get called with count=0? */
56+
double timeout_started;
57+
58+
/* None for autocommit, otherwise a PyString with the isolation level */
59+
PyObject* isolation_level;
60+
61+
/* NULL for autocommit, otherwise a string with the BEGIN statment; will be
62+
* freed in connection destructor */
63+
char* begin_statement;
64+
65+
/* 1 if a check should be performed for each API call if the connection is
66+
* used from the same thread it was created in */
67+
int check_same_thread;
68+
69+
int initialized;
70+
71+
/* thread identification of the thread the connection was created in */
72+
long thread_ident;
73+
74+
pysqlite_Cache* statement_cache;
75+
76+
/* Lists of weak references to statements and cursors used within this connection */
77+
PyObject* statements;
78+
PyObject* cursors;
79+
80+
/* Counters for how many statements/cursors were created in the connection. May be
81+
* reset to 0 at certain intervals */
82+
int created_statements;
83+
int created_cursors;
84+
85+
PyObject* row_factory;
86+
87+
/* Determines how bytestrings from SQLite are converted to Python objects:
88+
* - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings
89+
* - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created.
90+
* - PyString_Type: PyStrings are created as-is.
91+
* - Any custom callable: Any object returned from the callable called with the bytestring
92+
* as single parameter.
93+
*/
94+
PyObject* text_factory;
95+
96+
/* remember references to functions/classes used in
97+
* create_function/create/aggregate, use these as dictionary keys, so we
98+
* can keep the total system refcount constant by clearing that dictionary
99+
* in connection_dealloc */
100+
PyObject* function_pinboard;
101+
102+
/* a dictionary of registered collation name => collation callable mappings */
103+
PyObject* collations;
104+
105+
/* if our connection was created from a APSW connection, we keep a
106+
* reference to the APSW connection around and get rid of it in our
107+
* destructor */
108+
PyObject* apsw_connection;
109+
110+
/* Exception objects */
111+
PyObject* Warning;
112+
PyObject* Error;
113+
PyObject* InterfaceError;
114+
PyObject* DatabaseError;
115+
PyObject* DataError;
116+
PyObject* OperationalError;
117+
PyObject* IntegrityError;
118+
PyObject* InternalError;
119+
PyObject* ProgrammingError;
120+
PyObject* NotSupportedError;
121+
} pysqlite_Connection;
122+
123+
extern PyTypeObject pysqlite_ConnectionType;
124+
125+
PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware);
126+
void pysqlite_connection_dealloc(pysqlite_Connection* self);
127+
PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs);
128+
PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args);
129+
PyObject* _pysqlite_connection_begin(pysqlite_Connection* self);
130+
PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args);
131+
PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args);
132+
PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
133+
int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs);
134+
135+
int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor);
136+
int pysqlite_check_thread(pysqlite_Connection* self);
137+
int pysqlite_check_connection(pysqlite_Connection* con);
138+
139+
int pysqlite_connection_setup_types(void);
140+
141+
#endif

‎python/pyspatialite/src/cursor.c

Lines changed: 1126 additions & 0 deletions
Large diffs are not rendered by default.

‎python/pyspatialite/src/cursor.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* cursor.h - definitions for the cursor type
2+
*
3+
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_CURSOR_H
25+
#define PYSQLITE_CURSOR_H
26+
#include "Python.h"
27+
28+
#include "statement.h"
29+
#include "connection.h"
30+
#include "module.h"
31+
32+
typedef struct
33+
{
34+
PyObject_HEAD
35+
pysqlite_Connection* connection;
36+
PyObject* description;
37+
PyObject* row_cast_map;
38+
int arraysize;
39+
PyObject* lastrowid;
40+
long rowcount;
41+
PyObject* row_factory;
42+
pysqlite_Statement* statement;
43+
int closed;
44+
int reset;
45+
int initialized;
46+
47+
/* the next row to be returned, NULL if no next row available */
48+
PyObject* next_row;
49+
50+
PyObject* in_weakreflist; /* List of weak references */
51+
} pysqlite_Cursor;
52+
53+
typedef enum {
54+
STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
55+
STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
56+
STATEMENT_OTHER
57+
} pysqlite_StatementKind;
58+
59+
extern PyTypeObject pysqlite_CursorType;
60+
61+
PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args);
62+
PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args);
63+
PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self);
64+
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self);
65+
PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args);
66+
PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs);
67+
PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args);
68+
PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args);
69+
PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args);
70+
71+
int pysqlite_cursor_setup_types(void);
72+
73+
#define UNKNOWN (-1)
74+
#endif
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/* microprotocols.c - minimalist and non-validating protocols implementation
2+
*
3+
* Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
4+
*
5+
* This file is part of psycopg and was adapted for pysqlite. Federico Di
6+
* Gregorio gave the permission to use it within pysqlite under the following
7+
* license:
8+
*
9+
* This software is provided 'as-is', without any express or implied
10+
* warranty. In no event will the authors be held liable for any damages
11+
* arising from the use of this software.
12+
*
13+
* Permission is granted to anyone to use this software for any purpose,
14+
* including commercial applications, and to alter it and redistribute it
15+
* freely, subject to the following restrictions:
16+
*
17+
* 1. The origin of this software must not be misrepresented; you must not
18+
* claim that you wrote the original software. If you use this software
19+
* in a product, an acknowledgment in the product documentation would be
20+
* appreciated but is not required.
21+
* 2. Altered source versions must be plainly marked as such, and must not be
22+
* misrepresented as being the original software.
23+
* 3. This notice may not be removed or altered from any source distribution.
24+
*/
25+
26+
#include <Python.h>
27+
#include <structmember.h>
28+
29+
#include "cursor.h"
30+
#include "microprotocols.h"
31+
#include "prepare_protocol.h"
32+
33+
34+
/** the adapters registry **/
35+
36+
PyObject *psyco_adapters;
37+
38+
/* pysqlite_microprotocols_init - initialize the adapters dictionary */
39+
40+
int
41+
pysqlite_microprotocols_init(PyObject *dict)
42+
{
43+
/* create adapters dictionary and put it in module namespace */
44+
if ((psyco_adapters = PyDict_New()) == NULL) {
45+
return -1;
46+
}
47+
48+
return PyDict_SetItemString(dict, "adapters", psyco_adapters);
49+
}
50+
51+
52+
/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */
53+
54+
int
55+
pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
56+
{
57+
PyObject* key;
58+
int rc;
59+
60+
if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType;
61+
62+
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
63+
if (!key) {
64+
return -1;
65+
}
66+
67+
rc = PyDict_SetItem(psyco_adapters, key, cast);
68+
Py_DECREF(key);
69+
70+
return rc;
71+
}
72+
73+
/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */
74+
75+
PyObject *
76+
pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
77+
{
78+
PyObject *adapter, *key;
79+
80+
/* we don't check for exact type conformance as specified in PEP 246
81+
because the pysqlite_PrepareProtocolType type is abstract and there is no
82+
way to get a quotable object to be its instance */
83+
84+
/* look for an adapter in the registry */
85+
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
86+
if (!key) {
87+
return NULL;
88+
}
89+
adapter = PyDict_GetItem(psyco_adapters, key);
90+
Py_DECREF(key);
91+
if (adapter) {
92+
PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
93+
return adapted;
94+
}
95+
96+
/* try to have the protocol adapt this object*/
97+
if (PyObject_HasAttrString(proto, "__adapt__")) {
98+
PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
99+
if (adapted) {
100+
if (adapted != Py_None) {
101+
return adapted;
102+
} else {
103+
Py_DECREF(adapted);
104+
}
105+
}
106+
107+
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
108+
return NULL;
109+
}
110+
111+
/* and finally try to have the object adapt itself */
112+
if (PyObject_HasAttrString(obj, "__conform__")) {
113+
PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
114+
if (adapted) {
115+
if (adapted != Py_None) {
116+
return adapted;
117+
} else {
118+
Py_DECREF(adapted);
119+
}
120+
}
121+
122+
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
123+
return NULL;
124+
}
125+
}
126+
127+
/* else set the right exception and return NULL */
128+
PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
129+
return NULL;
130+
}
131+
132+
/** module-level functions **/
133+
134+
PyObject *
135+
pysqlite_adapt(pysqlite_Cursor *self, PyObject *args)
136+
{
137+
PyObject *obj, *alt = NULL;
138+
PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType;
139+
140+
if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
141+
return pysqlite_microprotocols_adapt(obj, proto, alt);
142+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* microprotocols.c - definitions for minimalist and non-validating protocols
2+
*
3+
* Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
4+
*
5+
* This file is part of psycopg and was adapted for pysqlite. Federico Di
6+
* Gregorio gave the permission to use it within pysqlite under the following
7+
* license:
8+
*
9+
* This software is provided 'as-is', without any express or implied
10+
* warranty. In no event will the authors be held liable for any damages
11+
* arising from the use of this software.
12+
*
13+
* Permission is granted to anyone to use this software for any purpose,
14+
* including commercial applications, and to alter it and redistribute it
15+
* freely, subject to the following restrictions:
16+
*
17+
* 1. The origin of this software must not be misrepresented; you must not
18+
* claim that you wrote the original software. If you use this software
19+
* in a product, an acknowledgment in the product documentation would be
20+
* appreciated but is not required.
21+
* 2. Altered source versions must be plainly marked as such, and must not be
22+
* misrepresented as being the original software.
23+
* 3. This notice may not be removed or altered from any source distribution.
24+
*/
25+
26+
#ifndef PSYCOPG_MICROPROTOCOLS_H
27+
#define PSYCOPG_MICROPROTOCOLS_H 1
28+
29+
#include <Python.h>
30+
31+
/** adapters registry **/
32+
33+
extern PyObject *psyco_adapters;
34+
35+
/** the names of the three mandatory methods **/
36+
37+
#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
38+
#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
39+
#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
40+
41+
/** exported functions **/
42+
43+
/* used by module.c to init the microprotocols system */
44+
extern int pysqlite_microprotocols_init(PyObject *dict);
45+
extern int pysqlite_microprotocols_add(
46+
PyTypeObject *type, PyObject *proto, PyObject *cast);
47+
extern PyObject *pysqlite_microprotocols_adapt(
48+
PyObject *obj, PyObject *proto, PyObject *alt);
49+
50+
extern PyObject *
51+
pysqlite_adapt(pysqlite_Cursor* self, PyObject *args);
52+
#define pysqlite_adapt_doc \
53+
"adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard."
54+
55+
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */

‎python/pyspatialite/src/module.c

Lines changed: 457 additions & 0 deletions
Large diffs are not rendered by default.

‎python/pyspatialite/src/module.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* module.h - definitions for the module
2+
*
3+
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_MODULE_H
25+
#define PYSQLITE_MODULE_H
26+
#include "Python.h"
27+
28+
#define PYSPATIALITE_VERSION "2.6.1"
29+
30+
extern PyObject* pysqlite_Error;
31+
extern PyObject* pysqlite_Warning;
32+
extern PyObject* pysqlite_InterfaceError;
33+
extern PyObject* pysqlite_DatabaseError;
34+
extern PyObject* pysqlite_InternalError;
35+
extern PyObject* pysqlite_OperationalError;
36+
extern PyObject* pysqlite_ProgrammingError;
37+
extern PyObject* pysqlite_IntegrityError;
38+
extern PyObject* pysqlite_DataError;
39+
extern PyObject* pysqlite_NotSupportedError;
40+
41+
extern PyObject* pysqlite_OptimizedUnicode;
42+
43+
/* the functions time.time() and time.sleep() */
44+
extern PyObject* time_time;
45+
extern PyObject* time_sleep;
46+
47+
/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
48+
* functions, that convert the SQL value to the appropriate Python value.
49+
* The key is uppercase.
50+
*/
51+
extern PyObject* converters;
52+
53+
extern int _enable_callback_tracebacks;
54+
extern int pysqlite_BaseTypeAdapted;
55+
56+
#define PARSE_DECLTYPES 1
57+
#define PARSE_COLNAMES 2
58+
#endif
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* prepare_protocol.c - the protocol for preparing values for SQLite
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#include "sqlitecompat.h"
25+
#include "prepare_protocol.h"
26+
27+
int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs)
28+
{
29+
return 0;
30+
}
31+
32+
void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self)
33+
{
34+
Py_TYPE(self)->tp_free((PyObject*)self);
35+
}
36+
37+
PyTypeObject pysqlite_PrepareProtocolType= {
38+
PyVarObject_HEAD_INIT(NULL, 0)
39+
MODULE_NAME ".PrepareProtocol", /* tp_name */
40+
sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */
41+
0, /* tp_itemsize */
42+
(destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */
43+
0, /* tp_print */
44+
0, /* tp_getattr */
45+
0, /* tp_setattr */
46+
0, /* tp_compare */
47+
0, /* tp_repr */
48+
0, /* tp_as_number */
49+
0, /* tp_as_sequence */
50+
0, /* tp_as_mapping */
51+
0, /* tp_hash */
52+
0, /* tp_call */
53+
0, /* tp_str */
54+
0, /* tp_getattro */
55+
0, /* tp_setattro */
56+
0, /* tp_as_buffer */
57+
Py_TPFLAGS_DEFAULT, /* tp_flags */
58+
0, /* tp_doc */
59+
0, /* tp_traverse */
60+
0, /* tp_clear */
61+
0, /* tp_richcompare */
62+
0, /* tp_weaklistoffset */
63+
0, /* tp_iter */
64+
0, /* tp_iternext */
65+
0, /* tp_methods */
66+
0, /* tp_members */
67+
0, /* tp_getset */
68+
0, /* tp_base */
69+
0, /* tp_dict */
70+
0, /* tp_descr_get */
71+
0, /* tp_descr_set */
72+
0, /* tp_dictoffset */
73+
(initproc)pysqlite_prepare_protocol_init, /* tp_init */
74+
0, /* tp_alloc */
75+
0, /* tp_new */
76+
0 /* tp_free */
77+
};
78+
79+
extern int pysqlite_prepare_protocol_setup_types(void)
80+
{
81+
pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew;
82+
Py_TYPE(&pysqlite_PrepareProtocolType)= &PyType_Type;
83+
return PyType_Ready(&pysqlite_PrepareProtocolType);
84+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* prepare_protocol.h - the protocol for preparing values for SQLite
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_PREPARE_PROTOCOL_H
25+
#define PYSQLITE_PREPARE_PROTOCOL_H
26+
#include "Python.h"
27+
28+
typedef struct
29+
{
30+
PyObject_HEAD
31+
} pysqlite_PrepareProtocol;
32+
33+
extern PyTypeObject pysqlite_PrepareProtocolType;
34+
35+
int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs);
36+
void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self);
37+
38+
int pysqlite_prepare_protocol_setup_types(void);
39+
40+
#define UNKNOWN (-1)
41+
#endif

‎python/pyspatialite/src/row.c

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
/* row.c - an enhanced tuple for database rows
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#include "row.h"
25+
#include "cursor.h"
26+
#include "sqlitecompat.h"
27+
28+
void pysqlite_row_dealloc(pysqlite_Row* self)
29+
{
30+
Py_XDECREF(self->data);
31+
Py_XDECREF(self->description);
32+
33+
Py_TYPE(self)->tp_free((PyObject*)self);
34+
}
35+
36+
int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
37+
{
38+
PyObject* data;
39+
pysqlite_Cursor* cursor;
40+
41+
self->data = 0;
42+
self->description = 0;
43+
44+
if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
45+
return -1;
46+
}
47+
48+
if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) {
49+
PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
50+
return -1;
51+
}
52+
53+
if (!PyTuple_Check(data)) {
54+
PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
55+
return -1;
56+
}
57+
58+
Py_INCREF(data);
59+
self->data = data;
60+
61+
Py_INCREF(cursor->description);
62+
self->description = cursor->description;
63+
64+
return 0;
65+
}
66+
67+
PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
68+
{
69+
long _idx;
70+
char* key;
71+
int nitems, i;
72+
char* compare_key;
73+
74+
char* p1;
75+
char* p2;
76+
77+
PyObject* item;
78+
79+
if (PyInt_Check(idx)) {
80+
_idx = PyInt_AsLong(idx);
81+
item = PyTuple_GetItem(self->data, _idx);
82+
Py_XINCREF(item);
83+
return item;
84+
} else if (PyLong_Check(idx)) {
85+
_idx = PyLong_AsLong(idx);
86+
item = PyTuple_GetItem(self->data, _idx);
87+
Py_XINCREF(item);
88+
return item;
89+
} else if (PyString_Check(idx)) {
90+
key = PyString_AsString(idx);
91+
92+
nitems = PyTuple_Size(self->description);
93+
94+
for (i = 0; i < nitems; i++) {
95+
compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
96+
if (!compare_key) {
97+
return NULL;
98+
}
99+
100+
p1 = key;
101+
p2 = compare_key;
102+
103+
while (1) {
104+
if ((*p1 == (char)0) || (*p2 == (char)0)) {
105+
break;
106+
}
107+
108+
if ((*p1 | 0x20) != (*p2 | 0x20)) {
109+
break;
110+
}
111+
112+
p1++;
113+
p2++;
114+
}
115+
116+
if ((*p1 == (char)0) && (*p2 == (char)0)) {
117+
/* found item */
118+
item = PyTuple_GetItem(self->data, i);
119+
Py_INCREF(item);
120+
return item;
121+
}
122+
123+
}
124+
125+
PyErr_SetString(PyExc_IndexError, "No item with that key");
126+
return NULL;
127+
} else if (PySlice_Check(idx)) {
128+
PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
129+
return NULL;
130+
} else {
131+
PyErr_SetString(PyExc_IndexError, "Index must be int or string");
132+
return NULL;
133+
}
134+
}
135+
136+
Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
137+
{
138+
return PyTuple_GET_SIZE(self->data);
139+
}
140+
141+
PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
142+
{
143+
PyObject* list;
144+
int nitems, i;
145+
146+
list = PyList_New(0);
147+
if (!list) {
148+
return NULL;
149+
}
150+
nitems = PyTuple_Size(self->description);
151+
152+
for (i = 0; i < nitems; i++) {
153+
if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) {
154+
Py_DECREF(list);
155+
return NULL;
156+
}
157+
}
158+
159+
return list;
160+
}
161+
162+
static int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags)
163+
{
164+
return (&PyTuple_Type)->tp_print(self->data, fp, flags);
165+
}
166+
167+
static PyObject* pysqlite_iter(pysqlite_Row* self)
168+
{
169+
return PyObject_GetIter(self->data);
170+
}
171+
172+
static long pysqlite_row_hash(pysqlite_Row *self)
173+
{
174+
return PyObject_Hash(self->description) ^ PyObject_Hash(self->data);
175+
}
176+
177+
static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
178+
{
179+
if (opid != Py_EQ && opid != Py_NE) {
180+
Py_INCREF(Py_NotImplemented);
181+
return Py_NotImplemented;
182+
}
183+
if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
184+
pysqlite_Row *other = (pysqlite_Row *)_other;
185+
PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
186+
if ((opid == Py_EQ && res == Py_True)
187+
|| (opid == Py_NE && res == Py_False)) {
188+
Py_DECREF(res);
189+
return PyObject_RichCompare(self->data, other->data, opid);
190+
}
191+
}
192+
Py_INCREF(Py_NotImplemented);
193+
return Py_NotImplemented;
194+
}
195+
196+
PyMappingMethods pysqlite_row_as_mapping = {
197+
/* mp_length */ (lenfunc)pysqlite_row_length,
198+
/* mp_subscript */ (binaryfunc)pysqlite_row_subscript,
199+
/* mp_ass_subscript */ (objobjargproc)0,
200+
};
201+
202+
static PyMethodDef pysqlite_row_methods[] = {
203+
{"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
204+
PyDoc_STR("Returns the keys of the row.")},
205+
{NULL, NULL}
206+
};
207+
208+
209+
PyTypeObject pysqlite_RowType = {
210+
PyVarObject_HEAD_INIT(NULL, 0)
211+
MODULE_NAME ".Row", /* tp_name */
212+
sizeof(pysqlite_Row), /* tp_basicsize */
213+
0, /* tp_itemsize */
214+
(destructor)pysqlite_row_dealloc, /* tp_dealloc */
215+
(printfunc)pysqlite_row_print, /* tp_print */
216+
0, /* tp_getattr */
217+
0, /* tp_setattr */
218+
0, /* tp_compare */
219+
0, /* tp_repr */
220+
0, /* tp_as_number */
221+
0, /* tp_as_sequence */
222+
0, /* tp_as_mapping */
223+
(hashfunc)pysqlite_row_hash, /* tp_hash */
224+
0, /* tp_call */
225+
0, /* tp_str */
226+
0, /* tp_getattro */
227+
0, /* tp_setattro */
228+
0, /* tp_as_buffer */
229+
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
230+
0, /* tp_doc */
231+
(traverseproc)0, /* tp_traverse */
232+
0, /* tp_clear */
233+
(richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */
234+
0, /* tp_weaklistoffset */
235+
(getiterfunc)pysqlite_iter, /* tp_iter */
236+
0, /* tp_iternext */
237+
pysqlite_row_methods, /* tp_methods */
238+
0, /* tp_members */
239+
0, /* tp_getset */
240+
0, /* tp_base */
241+
0, /* tp_dict */
242+
0, /* tp_descr_get */
243+
0, /* tp_descr_set */
244+
0, /* tp_dictoffset */
245+
(initproc)pysqlite_row_init, /* tp_init */
246+
0, /* tp_alloc */
247+
0, /* tp_new */
248+
0 /* tp_free */
249+
};
250+
251+
extern int pysqlite_row_setup_types(void)
252+
{
253+
pysqlite_RowType.tp_new = PyType_GenericNew;
254+
pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
255+
return PyType_Ready(&pysqlite_RowType);
256+
}

‎python/pyspatialite/src/row.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* row.h - an enhanced tuple for database rows
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_ROW_H
25+
#define PYSQLITE_ROW_H
26+
#include "Python.h"
27+
28+
typedef struct _Row
29+
{
30+
PyObject_HEAD
31+
PyObject* data;
32+
PyObject* description;
33+
} pysqlite_Row;
34+
35+
extern PyTypeObject pysqlite_RowType;
36+
37+
int pysqlite_row_setup_types(void);
38+
39+
#endif
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* sqlitecompat.h - compatibility macros
2+
*
3+
* Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#include "Python.h"
25+
26+
#ifndef PYSQLITE_COMPAT_H
27+
#define PYSQLITE_COMPAT_H
28+
29+
/* define Py_ssize_t for pre-2.5 versions of Python */
30+
31+
#if PY_VERSION_HEX < 0x02050000
32+
typedef int Py_ssize_t;
33+
typedef int (*lenfunc)(PyObject*);
34+
#endif
35+
36+
37+
/* define PyDict_CheckExact for pre-2.4 versions of Python */
38+
#ifndef PyDict_CheckExact
39+
#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type)
40+
#endif
41+
42+
/* define Py_CLEAR for pre-2.4 versions of Python */
43+
#ifndef Py_CLEAR
44+
#define Py_CLEAR(op) \
45+
do { \
46+
if (op) { \
47+
PyObject *tmp = (PyObject *)(op); \
48+
(op) = NULL; \
49+
Py_DECREF(tmp); \
50+
} \
51+
} while (0)
52+
#endif
53+
54+
#ifndef PyVarObject_HEAD_INIT
55+
#define PyVarObject_HEAD_INIT(type, size) \
56+
PyObject_HEAD_INIT(type) size,
57+
#endif
58+
59+
#ifndef Py_TYPE
60+
#define Py_TYPE(ob) ((ob)->ob_type)
61+
#endif
62+
63+
#endif

‎python/pyspatialite/src/statement.c

Lines changed: 543 additions & 0 deletions
Large diffs are not rendered by default.

‎python/pyspatialite/src/statement.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/* statement.h - definitions for the statement type
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_STATEMENT_H
25+
#define PYSQLITE_STATEMENT_H
26+
#include "Python.h"
27+
28+
#include "connection.h"
29+
#include "sqlite3.h"
30+
31+
#define PYSQLITE_TOO_MUCH_SQL (-100)
32+
#define PYSQLITE_SQL_WRONG_TYPE (-101)
33+
34+
typedef struct
35+
{
36+
PyObject_HEAD
37+
sqlite3* db;
38+
sqlite3_stmt* st;
39+
PyObject* sql;
40+
int in_use;
41+
PyObject* in_weakreflist; /* List of weak references */
42+
} pysqlite_Statement;
43+
44+
extern PyTypeObject pysqlite_StatementType;
45+
46+
int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql);
47+
void pysqlite_statement_dealloc(pysqlite_Statement* self);
48+
49+
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars);
50+
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars);
51+
52+
int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters);
53+
int pysqlite_statement_finalize(pysqlite_Statement* self);
54+
int pysqlite_statement_reset(pysqlite_Statement* self);
55+
void pysqlite_statement_mark_dirty(pysqlite_Statement* self);
56+
57+
int pysqlite_statement_setup_types(void);
58+
59+
#endif

‎python/pyspatialite/src/util.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* util.c - various utility functions
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#include "module.h"
25+
#include "connection.h"
26+
27+
int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection)
28+
{
29+
int rc;
30+
31+
if (statement == NULL) {
32+
/* this is a workaround for SQLite 3.5 and later. it now apparently
33+
* returns NULL for "no-operation" statements */
34+
rc = SQLITE_OK;
35+
} else {
36+
Py_BEGIN_ALLOW_THREADS
37+
rc = sqlite3_step(statement);
38+
Py_END_ALLOW_THREADS
39+
}
40+
41+
return rc;
42+
}
43+
44+
/**
45+
* Checks the SQLite error code and sets the appropriate DB-API exception.
46+
* Returns the error code (0 means no error occurred).
47+
*/
48+
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
49+
{
50+
int errorcode;
51+
52+
/* SQLite often doesn't report anything useful, unless you reset the statement first */
53+
if (st != NULL) {
54+
(void)sqlite3_reset(st);
55+
}
56+
57+
errorcode = sqlite3_errcode(db);
58+
59+
switch (errorcode)
60+
{
61+
case SQLITE_OK:
62+
PyErr_Clear();
63+
break;
64+
case SQLITE_INTERNAL:
65+
case SQLITE_NOTFOUND:
66+
PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db));
67+
break;
68+
case SQLITE_NOMEM:
69+
(void)PyErr_NoMemory();
70+
break;
71+
case SQLITE_ERROR:
72+
case SQLITE_PERM:
73+
case SQLITE_ABORT:
74+
case SQLITE_BUSY:
75+
case SQLITE_LOCKED:
76+
case SQLITE_READONLY:
77+
case SQLITE_INTERRUPT:
78+
case SQLITE_IOERR:
79+
case SQLITE_FULL:
80+
case SQLITE_CANTOPEN:
81+
case SQLITE_PROTOCOL:
82+
case SQLITE_EMPTY:
83+
case SQLITE_SCHEMA:
84+
PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db));
85+
break;
86+
case SQLITE_CORRUPT:
87+
PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
88+
break;
89+
case SQLITE_TOOBIG:
90+
PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db));
91+
break;
92+
case SQLITE_CONSTRAINT:
93+
case SQLITE_MISMATCH:
94+
PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db));
95+
break;
96+
case SQLITE_MISUSE:
97+
PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db));
98+
break;
99+
default:
100+
PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
101+
break;
102+
}
103+
104+
return errorcode;
105+
}
106+

‎python/pyspatialite/src/util.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* util.h - various utility functions
2+
*
3+
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4+
*
5+
* This file is part of pysqlite.
6+
*
7+
* This software is provided 'as-is', without any express or implied
8+
* warranty. In no event will the authors be held liable for any damages
9+
* arising from the use of this software.
10+
*
11+
* Permission is granted to anyone to use this software for any purpose,
12+
* including commercial applications, and to alter it and redistribute it
13+
* freely, subject to the following restrictions:
14+
*
15+
* 1. The origin of this software must not be misrepresented; you must not
16+
* claim that you wrote the original software. If you use this software
17+
* in a product, an acknowledgment in the product documentation would be
18+
* appreciated but is not required.
19+
* 2. Altered source versions must be plainly marked as such, and must not be
20+
* misrepresented as being the original software.
21+
* 3. This notice may not be removed or altered from any source distribution.
22+
*/
23+
24+
#ifndef PYSQLITE_UTIL_H
25+
#define PYSQLITE_UTIL_H
26+
#include "Python.h"
27+
#include "pythread.h"
28+
#include "sqlite3.h"
29+
#include "connection.h"
30+
31+
int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection);
32+
33+
/**
34+
* Checks the SQLite error code and sets the appropriate DB-API exception.
35+
* Returns the error code (0 means no error occurred).
36+
*/
37+
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
38+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.