History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules/_sqlite (19 of 3706 files). Show all

Unified · Split

19 files
  1. sys/src/cmd/python/Modules/_sqlite/cache.c +375 −0
  2. sys/src/cmd/python/Modules/_sqlite/cache.h +73 −0
  3. sys/src/cmd/python/Modules/_sqlite/connection.c +1255 −0
  4. sys/src/cmd/python/Modules/_sqlite/connection.h +129 −0
  5. sys/src/cmd/python/Modules/_sqlite/cursor.c +1057 −0
  6. sys/src/cmd/python/Modules/_sqlite/cursor.h +71 −0
  7. sys/src/cmd/python/Modules/_sqlite/microprotocols.c +142 −0
  8. sys/src/cmd/python/Modules/_sqlite/microprotocols.h +59 −0
  9. sys/src/cmd/python/Modules/_sqlite/module.c +409 −0
  10. sys/src/cmd/python/Modules/_sqlite/module.h +57 −0
  11. sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c +84 −0
  12. sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h +41 −0
  13. sys/src/cmd/python/Modules/_sqlite/row.c +202 −0
  14. sys/src/cmd/python/Modules/_sqlite/row.h +39 −0
  15. sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h +34 −0
  16. sys/src/cmd/python/Modules/_sqlite/statement.c +432 −0
  17. sys/src/cmd/python/Modules/_sqlite/statement.h +59 −0
  18. sys/src/cmd/python/Modules/_sqlite/util.c +96 −0
  19. sys/src/cmd/python/Modules/_sqlite/util.h +38 −0
sys/src/cmd/python/Modules/_sqlite/cache.c+375−0
@@ -0,0 +1,375 @@
1+/* cache .c - a LRU cache
2+ *
3+ * Copyright (C) 2004-2006 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 "cache.h"
25+#include <limits.h>
26+
27+/* only used internally */
28+Node* new_node(PyObject* key, PyObject* data)
29+{
30+ Node* node;
31+
32+ node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
33+ if (!node) {
34+ return NULL;
35+ }
36+
37+ Py_INCREF(key);
38+ node->key = key;
39+
40+ Py_INCREF(data);
41+ node->data = data;
42+
43+ node->prev = NULL;
44+ node->next = NULL;
45+
46+ return node;
47+}
48+
49+void node_dealloc(Node* self)
50+{
51+ Py_DECREF(self->key);
52+ Py_DECREF(self->data);
53+
54+ self->ob_type->tp_free((PyObject*)self);
55+}
56+
57+int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
58+{
59+ PyObject* factory;
60+ int size = 10;
61+
62+ self->factory = NULL;
63+
64+ if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
65+ return -1;
66+ }
67+
68+ /* minimum cache size is 5 entries */
69+ if (size < 5) {
70+ size = 5;
71+ }
72+ self->size = size;
73+ self->first = NULL;
74+ self->last = NULL;
75+
76+ self->mapping = PyDict_New();
77+ if (!self->mapping) {
78+ return -1;
79+ }
80+
81+ Py_INCREF(factory);
82+ self->factory = factory;
83+
84+ self->decref_factory = 1;
85+
86+ return 0;
87+}
88+
89+void cache_dealloc(Cache* self)
90+{
91+ Node* node;
92+ Node* delete_node;
93+
94+ if (!self->factory) {
95+ /* constructor failed, just get out of here */
96+ return;
97+ }
98+
99+ /* iterate over all nodes and deallocate them */
100+ node = self->first;
101+ while (node) {
102+ delete_node = node;
103+ node = node->next;
104+ Py_DECREF(delete_node);
105+ }
106+
107+ if (self->decref_factory) {
108+ Py_DECREF(self->factory);
109+ }
110+ Py_DECREF(self->mapping);
111+
112+ self->ob_type->tp_free((PyObject*)self);
113+}
114+
115+PyObject* cache_get(Cache* self, PyObject* args)
116+{
117+ PyObject* key = args;
118+ Node* node;
119+ Node* ptr;
120+ PyObject* data;
121+
122+ node = (Node*)PyDict_GetItem(self->mapping, key);
123+ if (node) {
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 */
132+ if (node->prev && node->count > node->prev->count) {
133+ ptr = node->prev;
134+
135+ while (ptr->prev && node->count > ptr->prev->count) {
136+ ptr = ptr->prev;
137+ }
138+
139+ if (node->next) {
140+ node->next->prev = node->prev;
141+ } else {
142+ self->last = node->prev;
143+ }
144+ if (node->prev) {
145+ node->prev->next = node->next;
146+ }
147+ if (ptr->prev) {
148+ ptr->prev->next = node;
149+ } else {
150+ self->first = node;
151+ }
152+
153+ node->next = ptr;
154+ node->prev = ptr->prev;
155+ if (!node->prev) {
156+ self->first = node;
157+ }
158+ ptr->prev = node;
159+ }
160+ } 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+
165+ if (PyDict_Size(self->mapping) == self->size) {
166+ if (self->last) {
167+ node = self->last;
168+
169+ if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
170+ return NULL;
171+ }
172+
173+ if (node->prev) {
174+ node->prev->next = NULL;
175+ }
176+ self->last = node->prev;
177+ node->prev = NULL;
178+
179+ Py_DECREF(node);
180+ }
181+ }
182+
183+ data = PyObject_CallFunction(self->factory, "O", key);
184+
185+ if (!data) {
186+ return NULL;
187+ }
188+
189+ node = new_node(key, data);
190+ if (!node) {
191+ return NULL;
192+ }
193+ node->prev = self->last;
194+
195+ Py_DECREF(data);
196+
197+ if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
198+ Py_DECREF(node);
199+ return NULL;
200+ }
201+
202+ if (self->last) {
203+ self->last->next = node;
204+ } else {
205+ self->first = node;
206+ }
207+ self->last = node;
208+ }
209+
210+ Py_INCREF(node->data);
211+ return node->data;
212+}
213+
214+PyObject* cache_display(Cache* self, PyObject* args)
215+{
216+ Node* ptr;
217+ PyObject* prevkey;
218+ PyObject* nextkey;
219+ PyObject* fmt_args;
220+ PyObject* template;
221+ PyObject* display_str;
222+
223+ ptr = self->first;
224+
225+ while (ptr) {
226+ if (ptr->prev) {
227+ prevkey = ptr->prev->key;
228+ } else {
229+ prevkey = Py_None;
230+ }
231+ Py_INCREF(prevkey);
232+
233+ if (ptr->next) {
234+ nextkey = ptr->next->key;
235+ } else {
236+ nextkey = Py_None;
237+ }
238+ Py_INCREF(nextkey);
239+
240+ fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
241+ if (!fmt_args) {
242+ return NULL;
243+ }
244+ template = PyString_FromString("%s <- %s ->%s\n");
245+ if (!template) {
246+ return NULL;
247+ }
248+ display_str = PyString_Format(template, fmt_args);
249+ Py_DECREF(template);
250+ Py_DECREF(fmt_args);
251+ if (!display_str) {
252+ return NULL;
253+ }
254+ PyObject_Print(display_str, stdout, Py_PRINT_RAW);
255+ Py_DECREF(display_str);
256+
257+ Py_DECREF(prevkey);
258+ Py_DECREF(nextkey);
259+
260+ ptr = ptr->next;
261+ }
262+
263+ Py_INCREF(Py_None);
264+ return Py_None;
265+}
266+
267+static PyMethodDef cache_methods[] = {
268+ {"get", (PyCFunction)cache_get, METH_O,
269+ PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
270+ {"display", (PyCFunction)cache_display, METH_NOARGS,
271+ PyDoc_STR("For debugging only.")},
272+ {NULL, NULL}
273+};
274+
275+PyTypeObject NodeType = {
276+ PyObject_HEAD_INIT(NULL)
277+ 0, /* ob_size */
278+ MODULE_NAME "Node", /* tp_name */
279+ sizeof(Node), /* tp_basicsize */
280+ 0, /* tp_itemsize */
281+ (destructor)node_dealloc, /* tp_dealloc */
282+ 0, /* tp_print */
283+ 0, /* tp_getattr */
284+ 0, /* tp_setattr */
285+ 0, /* tp_compare */
286+ 0, /* tp_repr */
287+ 0, /* tp_as_number */
288+ 0, /* tp_as_sequence */
289+ 0, /* tp_as_mapping */
290+ 0, /* tp_hash */
291+ 0, /* tp_call */
292+ 0, /* tp_str */
293+ 0, /* tp_getattro */
294+ 0, /* tp_setattro */
295+ 0, /* tp_as_buffer */
296+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
297+ 0, /* tp_doc */
298+ 0, /* tp_traverse */
299+ 0, /* tp_clear */
300+ 0, /* tp_richcompare */
301+ 0, /* tp_weaklistoffset */
302+ 0, /* tp_iter */
303+ 0, /* tp_iternext */
304+ 0, /* tp_methods */
305+ 0, /* tp_members */
306+ 0, /* tp_getset */
307+ 0, /* tp_base */
308+ 0, /* tp_dict */
309+ 0, /* tp_descr_get */
310+ 0, /* tp_descr_set */
311+ 0, /* tp_dictoffset */
312+ (initproc)0, /* tp_init */
313+ 0, /* tp_alloc */
314+ 0, /* tp_new */
315+ 0 /* tp_free */
316+};
317+
318+PyTypeObject CacheType = {
319+ PyObject_HEAD_INIT(NULL)
320+ 0, /* ob_size */
321+ MODULE_NAME ".Cache", /* tp_name */
322+ sizeof(Cache), /* tp_basicsize */
323+ 0, /* tp_itemsize */
324+ (destructor)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)cache_init, /* tp_init */
356+ 0, /* tp_alloc */
357+ 0, /* tp_new */
358+ 0 /* tp_free */
359+};
360+
361+extern int cache_setup_types(void)
362+{
363+ int rc;
364+
365+ NodeType.tp_new = PyType_GenericNew;
366+ CacheType.tp_new = PyType_GenericNew;
367+
368+ rc = PyType_Ready(&NodeType);
369+ if (rc < 0) {
370+ return rc;
371+ }
372+
373+ rc = PyType_Ready(&CacheType);
374+ return rc;
375+}
sys/src/cmd/python/Modules/_sqlite/cache.h+73−0
@@ -0,0 +1,73 @@
1+/* cache.h - definitions for the LRU cache
2+ *
3+ * Copyright (C) 2004-2006 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 _Node
33+{
34+ PyObject_HEAD
35+ PyObject* key;
36+ PyObject* data;
37+ long count;
38+ struct _Node* prev;
39+ struct _Node* next;
40+} 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+ Node* first;
54+ 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+} Cache;
60+
61+extern PyTypeObject NodeType;
62+extern PyTypeObject CacheType;
63+
64+int node_init(Node* self, PyObject* args, PyObject* kwargs);
65+void node_dealloc(Node* self);
66+
67+int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
68+void cache_dealloc(Cache* self);
69+PyObject* cache_get(Cache* self, PyObject* args);
70+
71+int cache_setup_types(void);
72+
73+#endif
sys/src/cmd/python/Modules/_sqlite/connection.c+1255−0
@@ -0,0 +1,1255 @@
1+/* connection.c - the connection type
2+ *
3+ * Copyright (C) 2004-2006 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 "cache.h"
25+#include "module.h"
26+#include "connection.h"
27+#include "statement.h"
28+#include "cursor.h"
29+#include "prepare_protocol.h"
30+#include "util.h"
31+#include "sqlitecompat.h"
32+
33+#include "pythread.h"
34+
35+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
36+
37+
38+void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
39+{
40+ /* in older SQLite versions, calling sqlite3_result_error in callbacks
41+ * triggers a bug in SQLite that leads either to irritating results or
42+ * segfaults, depending on the SQLite version */
43+#if SQLITE_VERSION_NUMBER >= 3003003
44+ sqlite3_result_error(ctx, errmsg, len);
45+#else
46+ PyErr_SetString(OperationalError, errmsg);
47+#endif
48+}
49+
50+int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
51+{
52+ static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
53+
54+ char* database;
55+ int detect_types = 0;
56+ PyObject* isolation_level = NULL;
57+ PyObject* factory = NULL;
58+ int check_same_thread = 1;
59+ int cached_statements = 100;
60+ double timeout = 5.0;
61+ int rc;
62+
63+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
64+ &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
65+ {
66+ return -1;
67+ }
68+
69+ self->begin_statement = NULL;
70+
71+ self->statement_cache = NULL;
72+ self->statements = NULL;
73+
74+ Py_INCREF(Py_None);
75+ self->row_factory = Py_None;
76+
77+ Py_INCREF(&PyUnicode_Type);
78+ self->text_factory = (PyObject*)&PyUnicode_Type;
79+
80+ Py_BEGIN_ALLOW_THREADS
81+ rc = sqlite3_open(database, &self->db);
82+ Py_END_ALLOW_THREADS
83+
84+ if (rc != SQLITE_OK) {
85+ _seterror(self->db);
86+ return -1;
87+ }
88+
89+ if (!isolation_level) {
90+ isolation_level = PyString_FromString("");
91+ if (!isolation_level) {
92+ return -1;
93+ }
94+ } else {
95+ Py_INCREF(isolation_level);
96+ }
97+ self->isolation_level = NULL;
98+ connection_set_isolation_level(self, isolation_level);
99+ Py_DECREF(isolation_level);
100+
101+ self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "Oi", self, cached_statements);
102+ if (PyErr_Occurred()) {
103+ return -1;
104+ }
105+
106+ self->statements = PyList_New(0);
107+ if (!self->statements) {
108+ return -1;
109+ }
110+ self->created_statements = 0;
111+
112+ /* By default, the Cache class INCREFs the factory in its initializer, and
113+ * decrefs it in its deallocator method. Since this would create a circular
114+ * reference here, we're breaking it by decrementing self, and telling the
115+ * cache class to not decref the factory (self) in its deallocator.
116+ */
117+ self->statement_cache->decref_factory = 0;
118+ Py_DECREF(self);
119+
120+ self->inTransaction = 0;
121+ self->detect_types = detect_types;
122+ self->timeout = timeout;
123+ (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
124+
125+ self->thread_ident = PyThread_get_thread_ident();
126+ self->check_same_thread = check_same_thread;
127+
128+ self->function_pinboard = PyDict_New();
129+ if (!self->function_pinboard) {
130+ return -1;
131+ }
132+
133+ self->collations = PyDict_New();
134+ if (!self->collations) {
135+ return -1;
136+ }
137+
138+ self->Warning = Warning;
139+ self->Error = Error;
140+ self->InterfaceError = InterfaceError;
141+ self->DatabaseError = DatabaseError;
142+ self->DataError = DataError;
143+ self->OperationalError = OperationalError;
144+ self->IntegrityError = IntegrityError;
145+ self->InternalError = InternalError;
146+ self->ProgrammingError = ProgrammingError;
147+ self->NotSupportedError = NotSupportedError;
148+
149+ return 0;
150+}
151+
152+/* Empty the entire statement cache of this connection */
153+void flush_statement_cache(Connection* self)
154+{
155+ Node* node;
156+ Statement* statement;
157+
158+ node = self->statement_cache->first;
159+
160+ while (node) {
161+ statement = (Statement*)(node->data);
162+ (void)statement_finalize(statement);
163+ node = node->next;
164+ }
165+
166+ Py_DECREF(self->statement_cache);
167+ self->statement_cache = (Cache*)PyObject_CallFunction((PyObject*)&CacheType, "O", self);
168+ Py_DECREF(self);
169+ self->statement_cache->decref_factory = 0;
170+}
171+
172+void reset_all_statements(Connection* self)
173+{
174+ int i;
175+ PyObject* weakref;
176+ PyObject* statement;
177+
178+ for (i = 0; i < PyList_Size(self->statements); i++) {
179+ weakref = PyList_GetItem(self->statements, i);
180+ statement = PyWeakref_GetObject(weakref);
181+ if (statement != Py_None) {
182+ (void)statement_reset((Statement*)statement);
183+ }
184+ }
185+}
186+
187+void connection_dealloc(Connection* self)
188+{
189+ Py_XDECREF(self->statement_cache);
190+
191+ /* Clean up if user has not called .close() explicitly. */
192+ if (self->db) {
193+ Py_BEGIN_ALLOW_THREADS
194+ sqlite3_close(self->db);
195+ Py_END_ALLOW_THREADS
196+ }
197+
198+ if (self->begin_statement) {
199+ PyMem_Free(self->begin_statement);
200+ }
201+ Py_XDECREF(self->isolation_level);
202+ Py_XDECREF(self->function_pinboard);
203+ Py_XDECREF(self->row_factory);
204+ Py_XDECREF(self->text_factory);
205+ Py_XDECREF(self->collations);
206+ Py_XDECREF(self->statements);
207+
208+ self->ob_type->tp_free((PyObject*)self);
209+}
210+
211+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs)
212+{
213+ static char *kwlist[] = {"factory", NULL, NULL};
214+ PyObject* factory = NULL;
215+ PyObject* cursor;
216+
217+
218+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
219+ &factory)) {
220+ return NULL;
221+ }
222+
223+ if (!check_thread(self) || !check_connection(self)) {
224+ return NULL;
225+ }
226+
227+ if (factory == NULL) {
228+ factory = (PyObject*)&CursorType;
229+ }
230+
231+ cursor = PyObject_CallFunction(factory, "O", self);
232+
233+ if (cursor && self->row_factory != Py_None) {
234+ Py_XDECREF(((Cursor*)cursor)->row_factory);
235+ Py_INCREF(self->row_factory);
236+ ((Cursor*)cursor)->row_factory = self->row_factory;
237+ }
238+
239+ return cursor;
240+}
241+
242+PyObject* connection_close(Connection* self, PyObject* args)
243+{
244+ int rc;
245+
246+ if (!check_thread(self)) {
247+ return NULL;
248+ }
249+
250+ flush_statement_cache(self);
251+
252+ if (self->db) {
253+ Py_BEGIN_ALLOW_THREADS
254+ rc = sqlite3_close(self->db);
255+ Py_END_ALLOW_THREADS
256+
257+ if (rc != SQLITE_OK) {
258+ _seterror(self->db);
259+ return NULL;
260+ } else {
261+ self->db = NULL;
262+ }
263+ }
264+
265+ Py_INCREF(Py_None);
266+ return Py_None;
267+}
268+
269+/*
270+ * Checks if a connection object is usable (i. e. not closed).
271+ *
272+ * 0 => error; 1 => ok
273+ */
274+int check_connection(Connection* con)
275+{
276+ if (!con->db) {
277+ PyErr_SetString(ProgrammingError, "Cannot operate on a closed database.");
278+ return 0;
279+ } else {
280+ return 1;
281+ }
282+}
283+
284+PyObject* _connection_begin(Connection* self)
285+{
286+ int rc;
287+ const char* tail;
288+ sqlite3_stmt* statement;
289+
290+ Py_BEGIN_ALLOW_THREADS
291+ rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail);
292+ Py_END_ALLOW_THREADS
293+
294+ if (rc != SQLITE_OK) {
295+ _seterror(self->db);
296+ goto error;
297+ }
298+
299+ rc = _sqlite_step_with_busyhandler(statement, self);
300+ if (rc == SQLITE_DONE) {
301+ self->inTransaction = 1;
302+ } else {
303+ _seterror(self->db);
304+ }
305+
306+ Py_BEGIN_ALLOW_THREADS
307+ rc = sqlite3_finalize(statement);
308+ Py_END_ALLOW_THREADS
309+
310+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
311+ _seterror(self->db);
312+ }
313+
314+error:
315+ if (PyErr_Occurred()) {
316+ return NULL;
317+ } else {
318+ Py_INCREF(Py_None);
319+ return Py_None;
320+ }
321+}
322+
323+PyObject* connection_commit(Connection* self, PyObject* args)
324+{
325+ int rc;
326+ const char* tail;
327+ sqlite3_stmt* statement;
328+
329+ if (!check_thread(self) || !check_connection(self)) {
330+ return NULL;
331+ }
332+
333+ if (self->inTransaction) {
334+ Py_BEGIN_ALLOW_THREADS
335+ rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
336+ Py_END_ALLOW_THREADS
337+ if (rc != SQLITE_OK) {
338+ _seterror(self->db);
339+ goto error;
340+ }
341+
342+ rc = _sqlite_step_with_busyhandler(statement, self);
343+ if (rc == SQLITE_DONE) {
344+ self->inTransaction = 0;
345+ } else {
346+ _seterror(self->db);
347+ }
348+
349+ Py_BEGIN_ALLOW_THREADS
350+ rc = sqlite3_finalize(statement);
351+ Py_END_ALLOW_THREADS
352+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
353+ _seterror(self->db);
354+ }
355+
356+ }
357+
358+error:
359+ if (PyErr_Occurred()) {
360+ return NULL;
361+ } else {
362+ Py_INCREF(Py_None);
363+ return Py_None;
364+ }
365+}
366+
367+PyObject* connection_rollback(Connection* self, PyObject* args)
368+{
369+ int rc;
370+ const char* tail;
371+ sqlite3_stmt* statement;
372+
373+ if (!check_thread(self) || !check_connection(self)) {
374+ return NULL;
375+ }
376+
377+ if (self->inTransaction) {
378+ reset_all_statements(self);
379+
380+ Py_BEGIN_ALLOW_THREADS
381+ rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
382+ Py_END_ALLOW_THREADS
383+ if (rc != SQLITE_OK) {
384+ _seterror(self->db);
385+ goto error;
386+ }
387+
388+ rc = _sqlite_step_with_busyhandler(statement, self);
389+ if (rc == SQLITE_DONE) {
390+ self->inTransaction = 0;
391+ } else {
392+ _seterror(self->db);
393+ }
394+
395+ Py_BEGIN_ALLOW_THREADS
396+ rc = sqlite3_finalize(statement);
397+ Py_END_ALLOW_THREADS
398+ if (rc != SQLITE_OK && !PyErr_Occurred()) {
399+ _seterror(self->db);
400+ }
401+
402+ }
403+
404+error:
405+ if (PyErr_Occurred()) {
406+ return NULL;
407+ } else {
408+ Py_INCREF(Py_None);
409+ return Py_None;
410+ }
411+}
412+
413+void _set_result(sqlite3_context* context, PyObject* py_val)
414+{
415+ long longval;
416+ const char* buffer;
417+ Py_ssize_t buflen;
418+ PyObject* stringval;
419+
420+ if ((!py_val) || PyErr_Occurred()) {
421+ sqlite3_result_null(context);
422+ } else if (py_val == Py_None) {
423+ sqlite3_result_null(context);
424+ } else if (PyInt_Check(py_val)) {
425+ longval = PyInt_AsLong(py_val);
426+ sqlite3_result_int64(context, (PY_LONG_LONG)longval);
427+ } else if (PyFloat_Check(py_val)) {
428+ sqlite3_result_double(context, PyFloat_AsDouble(py_val));
429+ } else if (PyBuffer_Check(py_val)) {
430+ if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
431+ PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
432+ } else {
433+ sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
434+ }
435+ } else if (PyString_Check(py_val)) {
436+ sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
437+ } else if (PyUnicode_Check(py_val)) {
438+ stringval = PyUnicode_AsUTF8String(py_val);
439+ if (stringval) {
440+ sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
441+ Py_DECREF(stringval);
442+ }
443+ } else {
444+ /* TODO: raise error */
445+ }
446+}
447+
448+PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv)
449+{
450+ PyObject* args;
451+ int i;
452+ sqlite3_value* cur_value;
453+ PyObject* cur_py_value;
454+ const char* val_str;
455+ PY_LONG_LONG val_int;
456+ Py_ssize_t buflen;
457+ void* raw_buffer;
458+
459+ args = PyTuple_New(argc);
460+ if (!args) {
461+ return NULL;
462+ }
463+
464+ for (i = 0; i < argc; i++) {
465+ cur_value = argv[i];
466+ switch (sqlite3_value_type(argv[i])) {
467+ case SQLITE_INTEGER:
468+ val_int = sqlite3_value_int64(cur_value);
469+ cur_py_value = PyInt_FromLong((long)val_int);
470+ break;
471+ case SQLITE_FLOAT:
472+ cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
473+ break;
474+ case SQLITE_TEXT:
475+ val_str = (const char*)sqlite3_value_text(cur_value);
476+ cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
477+ /* TODO: have a way to show errors here */
478+ if (!cur_py_value) {
479+ PyErr_Clear();
480+ Py_INCREF(Py_None);
481+ cur_py_value = Py_None;
482+ }
483+ break;
484+ case SQLITE_BLOB:
485+ buflen = sqlite3_value_bytes(cur_value);
486+ cur_py_value = PyBuffer_New(buflen);
487+ if (!cur_py_value) {
488+ break;
489+ }
490+ if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) {
491+ Py_DECREF(cur_py_value);
492+ cur_py_value = NULL;
493+ break;
494+ }
495+ memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen);
496+ break;
497+ case SQLITE_NULL:
498+ default:
499+ Py_INCREF(Py_None);
500+ cur_py_value = Py_None;
501+ }
502+
503+ if (!cur_py_value) {
504+ Py_DECREF(args);
505+ return NULL;
506+ }
507+
508+ PyTuple_SetItem(args, i, cur_py_value);
509+
510+ }
511+
512+ return args;
513+}
514+
515+void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
516+{
517+ PyObject* args;
518+ PyObject* py_func;
519+ PyObject* py_retval = NULL;
520+
521+ PyGILState_STATE threadstate;
522+
523+ threadstate = PyGILState_Ensure();
524+
525+ py_func = (PyObject*)sqlite3_user_data(context);
526+
527+ args = _build_py_params(context, argc, argv);
528+ if (args) {
529+ py_retval = PyObject_CallObject(py_func, args);
530+ Py_DECREF(args);
531+ }
532+
533+ if (py_retval) {
534+ _set_result(context, py_retval);
535+ Py_DECREF(py_retval);
536+ } else {
537+ if (_enable_callback_tracebacks) {
538+ PyErr_Print();
539+ } else {
540+ PyErr_Clear();
541+ }
542+ _sqlite3_result_error(context, "user-defined function raised exception", -1);
543+ }
544+
545+ PyGILState_Release(threadstate);
546+}
547+
548+static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
549+{
550+ PyObject* args;
551+ PyObject* function_result = NULL;
552+ PyObject* aggregate_class;
553+ PyObject** aggregate_instance;
554+ PyObject* stepmethod = NULL;
555+
556+ PyGILState_STATE threadstate;
557+
558+ threadstate = PyGILState_Ensure();
559+
560+ aggregate_class = (PyObject*)sqlite3_user_data(context);
561+
562+ aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
563+
564+ if (*aggregate_instance == 0) {
565+ *aggregate_instance = PyObject_CallFunction(aggregate_class, "");
566+
567+ if (PyErr_Occurred()) {
568+ *aggregate_instance = 0;
569+ if (_enable_callback_tracebacks) {
570+ PyErr_Print();
571+ } else {
572+ PyErr_Clear();
573+ }
574+ _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
575+ goto error;
576+ }
577+ }
578+
579+ stepmethod = PyObject_GetAttrString(*aggregate_instance, "step");
580+ if (!stepmethod) {
581+ goto error;
582+ }
583+
584+ args = _build_py_params(context, argc, params);
585+ if (!args) {
586+ goto error;
587+ }
588+
589+ function_result = PyObject_CallObject(stepmethod, args);
590+ Py_DECREF(args);
591+
592+ if (!function_result) {
593+ if (_enable_callback_tracebacks) {
594+ PyErr_Print();
595+ } else {
596+ PyErr_Clear();
597+ }
598+ _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
599+ }
600+
601+error:
602+ Py_XDECREF(stepmethod);
603+ Py_XDECREF(function_result);
604+
605+ PyGILState_Release(threadstate);
606+}
607+
608+void _final_callback(sqlite3_context* context)
609+{
610+ PyObject* function_result = NULL;
611+ PyObject** aggregate_instance;
612+ PyObject* aggregate_class;
613+
614+ PyGILState_STATE threadstate;
615+
616+ threadstate = PyGILState_Ensure();
617+
618+ aggregate_class = (PyObject*)sqlite3_user_data(context);
619+
620+ aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
621+ if (!*aggregate_instance) {
622+ /* this branch is executed if there was an exception in the aggregate's
623+ * __init__ */
624+
625+ goto error;
626+ }
627+
628+ function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
629+ if (!function_result) {
630+ if (_enable_callback_tracebacks) {
631+ PyErr_Print();
632+ } else {
633+ PyErr_Clear();
634+ }
635+ _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
636+ } else {
637+ _set_result(context, function_result);
638+ }
639+
640+error:
641+ Py_XDECREF(*aggregate_instance);
642+ Py_XDECREF(function_result);
643+
644+ PyGILState_Release(threadstate);
645+}
646+
647+void _drop_unused_statement_references(Connection* self)
648+{
649+ PyObject* new_list;
650+ PyObject* weakref;
651+ int i;
652+
653+ /* we only need to do this once in a while */
654+ if (self->created_statements++ < 200) {
655+ return;
656+ }
657+
658+ self->created_statements = 0;
659+
660+ new_list = PyList_New(0);
661+ if (!new_list) {
662+ return;
663+ }
664+
665+ for (i = 0; i < PyList_Size(self->statements); i++) {
666+ weakref = PyList_GetItem(self->statements, i);
667+ if (PyWeakref_GetObject(weakref) != Py_None) {
668+ if (PyList_Append(new_list, weakref) != 0) {
669+ Py_DECREF(new_list);
670+ return;
671+ }
672+ }
673+ }
674+
675+ Py_DECREF(self->statements);
676+ self->statements = new_list;
677+}
678+
679+PyObject* connection_create_function(Connection* self, PyObject* args, PyObject* kwargs)
680+{
681+ static char *kwlist[] = {"name", "narg", "func", NULL, NULL};
682+
683+ PyObject* func;
684+ char* name;
685+ int narg;
686+ int rc;
687+
688+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist,
689+ &name, &narg, &func))
690+ {
691+ return NULL;
692+ }
693+
694+ rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _func_callback, NULL, NULL);
695+
696+ if (rc != SQLITE_OK) {
697+ /* Workaround for SQLite bug: no error code or string is available here */
698+ PyErr_SetString(OperationalError, "Error creating function");
699+ return NULL;
700+ } else {
701+ PyDict_SetItem(self->function_pinboard, func, Py_None);
702+
703+ Py_INCREF(Py_None);
704+ return Py_None;
705+ }
706+}
707+
708+PyObject* connection_create_aggregate(Connection* self, PyObject* args, PyObject* kwargs)
709+{
710+ PyObject* aggregate_class;
711+
712+ int n_arg;
713+ char* name;
714+ static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL };
715+ int rc;
716+
717+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate",
718+ kwlist, &name, &n_arg, &aggregate_class)) {
719+ return NULL;
720+ }
721+
722+ rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_step_callback, &_final_callback);
723+ if (rc != SQLITE_OK) {
724+ /* Workaround for SQLite bug: no error code or string is available here */
725+ PyErr_SetString(OperationalError, "Error creating aggregate");
726+ return NULL;
727+ } else {
728+ PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None);
729+
730+ Py_INCREF(Py_None);
731+ return Py_None;
732+ }
733+}
734+
735+int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source)
736+{
737+ PyObject *ret;
738+ int rc;
739+ PyGILState_STATE gilstate;
740+
741+ gilstate = PyGILState_Ensure();
742+ ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
743+
744+ if (!ret) {
745+ if (_enable_callback_tracebacks) {
746+ PyErr_Print();
747+ } else {
748+ PyErr_Clear();
749+ }
750+
751+ rc = SQLITE_DENY;
752+ } else {
753+ if (PyInt_Check(ret)) {
754+ rc = (int)PyInt_AsLong(ret);
755+ } else {
756+ rc = SQLITE_DENY;
757+ }
758+ Py_DECREF(ret);
759+ }
760+
761+ PyGILState_Release(gilstate);
762+ return rc;
763+}
764+
765+PyObject* connection_set_authorizer(Connection* self, PyObject* args, PyObject* kwargs)
766+{
767+ PyObject* authorizer_cb;
768+
769+ static char *kwlist[] = { "authorizer_callback", NULL };
770+ int rc;
771+
772+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer",
773+ kwlist, &authorizer_cb)) {
774+ return NULL;
775+ }
776+
777+ rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb);
778+
779+ if (rc != SQLITE_OK) {
780+ PyErr_SetString(OperationalError, "Error setting authorizer callback");
781+ return NULL;
782+ } else {
783+ PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None);
784+
785+ Py_INCREF(Py_None);
786+ return Py_None;
787+ }
788+}
789+
790+int check_thread(Connection* self)
791+{
792+ if (self->check_same_thread) {
793+ if (PyThread_get_thread_ident() != self->thread_ident) {
794+ PyErr_Format(ProgrammingError,
795+ "SQLite objects created in a thread can only be used in that same thread."
796+ "The object was created in thread id %ld and this is thread id %ld",
797+ self->thread_ident, PyThread_get_thread_ident());
798+ return 0;
799+ }
800+
801+ }
802+
803+ return 1;
804+}
805+
806+static PyObject* connection_get_isolation_level(Connection* self, void* unused)
807+{
808+ Py_INCREF(self->isolation_level);
809+ return self->isolation_level;
810+}
811+
812+static PyObject* connection_get_total_changes(Connection* self, void* unused)
813+{
814+ if (!check_connection(self)) {
815+ return NULL;
816+ } else {
817+ return Py_BuildValue("i", sqlite3_total_changes(self->db));
818+ }
819+}
820+
821+static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
822+{
823+ PyObject* res;
824+ PyObject* begin_statement;
825+
826+ Py_XDECREF(self->isolation_level);
827+
828+ if (self->begin_statement) {
829+ PyMem_Free(self->begin_statement);
830+ self->begin_statement = NULL;
831+ }
832+
833+ if (isolation_level == Py_None) {
834+ Py_INCREF(Py_None);
835+ self->isolation_level = Py_None;
836+
837+ res = connection_commit(self, NULL);
838+ if (!res) {
839+ return -1;
840+ }
841+ Py_DECREF(res);
842+
843+ self->inTransaction = 0;
844+ } else {
845+ Py_INCREF(isolation_level);
846+ self->isolation_level = isolation_level;
847+
848+ begin_statement = PyString_FromString("BEGIN ");
849+ if (!begin_statement) {
850+ return -1;
851+ }
852+ PyString_Concat(&begin_statement, isolation_level);
853+ if (!begin_statement) {
854+ return -1;
855+ }
856+
857+ self->begin_statement = PyMem_Malloc(PyString_Size(begin_statement) + 2);
858+ if (!self->begin_statement) {
859+ return -1;
860+ }
861+
862+ strcpy(self->begin_statement, PyString_AsString(begin_statement));
863+ Py_DECREF(begin_statement);
864+ }
865+
866+ return 0;
867+}
868+
869+PyObject* connection_call(Connection* self, PyObject* args, PyObject* kwargs)
870+{
871+ PyObject* sql;
872+ Statement* statement;
873+ PyObject* weakref;
874+ int rc;
875+
876+ if (!PyArg_ParseTuple(args, "O", &sql)) {
877+ return NULL;
878+ }
879+
880+ _drop_unused_statement_references(self);
881+
882+ statement = PyObject_New(Statement, &StatementType);
883+ if (!statement) {
884+ return NULL;
885+ }
886+
887+ rc = statement_create(statement, self, sql);
888+
889+ if (rc != SQLITE_OK) {
890+ if (rc == PYSQLITE_TOO_MUCH_SQL) {
891+ PyErr_SetString(Warning, "You can only execute one statement at a time.");
892+ } else if (rc == PYSQLITE_SQL_WRONG_TYPE) {
893+ PyErr_SetString(Warning, "SQL is of wrong type. Must be string or unicode.");
894+ } else {
895+ _seterror(self->db);
896+ }
897+
898+ Py_DECREF(statement);
899+ statement = 0;
900+ } else {
901+ weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
902+ if (!weakref) {
903+ Py_DECREF(statement);
904+ statement = 0;
905+ goto error;
906+ }
907+
908+ if (PyList_Append(self->statements, weakref) != 0) {
909+ Py_DECREF(weakref);
910+ statement = 0;
911+ goto error;
912+ }
913+
914+ Py_DECREF(weakref);
915+ }
916+
917+error:
918+ return (PyObject*)statement;
919+}
920+
921+PyObject* connection_execute(Connection* self, PyObject* args, PyObject* kwargs)
922+{
923+ PyObject* cursor = 0;
924+ PyObject* result = 0;
925+ PyObject* method = 0;
926+
927+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
928+ if (!cursor) {
929+ goto error;
930+ }
931+
932+ method = PyObject_GetAttrString(cursor, "execute");
933+ if (!method) {
934+ Py_DECREF(cursor);
935+ cursor = 0;
936+ goto error;
937+ }
938+
939+ result = PyObject_CallObject(method, args);
940+ if (!result) {
941+ Py_DECREF(cursor);
942+ cursor = 0;
943+ }
944+
945+error:
946+ Py_XDECREF(result);
947+ Py_XDECREF(method);
948+
949+ return cursor;
950+}
951+
952+PyObject* connection_executemany(Connection* self, PyObject* args, PyObject* kwargs)
953+{
954+ PyObject* cursor = 0;
955+ PyObject* result = 0;
956+ PyObject* method = 0;
957+
958+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
959+ if (!cursor) {
960+ goto error;
961+ }
962+
963+ method = PyObject_GetAttrString(cursor, "executemany");
964+ if (!method) {
965+ Py_DECREF(cursor);
966+ cursor = 0;
967+ goto error;
968+ }
969+
970+ result = PyObject_CallObject(method, args);
971+ if (!result) {
972+ Py_DECREF(cursor);
973+ cursor = 0;
974+ }
975+
976+error:
977+ Py_XDECREF(result);
978+ Py_XDECREF(method);
979+
980+ return cursor;
981+}
982+
983+PyObject* connection_executescript(Connection* self, PyObject* args, PyObject* kwargs)
984+{
985+ PyObject* cursor = 0;
986+ PyObject* result = 0;
987+ PyObject* method = 0;
988+
989+ cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
990+ if (!cursor) {
991+ goto error;
992+ }
993+
994+ method = PyObject_GetAttrString(cursor, "executescript");
995+ if (!method) {
996+ Py_DECREF(cursor);
997+ cursor = 0;
998+ goto error;
999+ }
1000+
1001+ result = PyObject_CallObject(method, args);
1002+ if (!result) {
1003+ Py_DECREF(cursor);
1004+ cursor = 0;
1005+ }
1006+
1007+error:
1008+ Py_XDECREF(result);
1009+ Py_XDECREF(method);
1010+
1011+ return cursor;
1012+}
1013+
1014+/* ------------------------- COLLATION CODE ------------------------ */
1015+
1016+static int
1017+collation_callback(
1018+ void* context,
1019+ int text1_length, const void* text1_data,
1020+ int text2_length, const void* text2_data)
1021+{
1022+ PyObject* callback = (PyObject*)context;
1023+ PyObject* string1 = 0;
1024+ PyObject* string2 = 0;
1025+ PyGILState_STATE gilstate;
1026+
1027+ PyObject* retval = NULL;
1028+ int result = 0;
1029+
1030+ gilstate = PyGILState_Ensure();
1031+
1032+ if (PyErr_Occurred()) {
1033+ goto finally;
1034+ }
1035+
1036+ string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length);
1037+ string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length);
1038+
1039+ if (!string1 || !string2) {
1040+ goto finally; /* failed to allocate strings */
1041+ }
1042+
1043+ retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL);
1044+
1045+ if (!retval) {
1046+ /* execution failed */
1047+ goto finally;
1048+ }
1049+
1050+ result = PyInt_AsLong(retval);
1051+ if (PyErr_Occurred()) {
1052+ result = 0;
1053+ }
1054+
1055+finally:
1056+ Py_XDECREF(string1);
1057+ Py_XDECREF(string2);
1058+ Py_XDECREF(retval);
1059+
1060+ PyGILState_Release(gilstate);
1061+
1062+ return result;
1063+}
1064+
1065+static PyObject *
1066+connection_interrupt(Connection* self, PyObject* args)
1067+{
1068+ PyObject* retval = NULL;
1069+
1070+ if (!check_connection(self)) {
1071+ goto finally;
1072+ }
1073+
1074+ sqlite3_interrupt(self->db);
1075+
1076+ Py_INCREF(Py_None);
1077+ retval = Py_None;
1078+
1079+finally:
1080+ return retval;
1081+}
1082+
1083+static PyObject *
1084+connection_create_collation(Connection* self, PyObject* args)
1085+{
1086+ PyObject* callable;
1087+ PyObject* uppercase_name = 0;
1088+ PyObject* name;
1089+ PyObject* retval;
1090+ char* chk;
1091+ int rc;
1092+
1093+ if (!check_thread(self) || !check_connection(self)) {
1094+ goto finally;
1095+ }
1096+
1097+ if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) {
1098+ goto finally;
1099+ }
1100+
1101+ uppercase_name = PyObject_CallMethod(name, "upper", "");
1102+ if (!uppercase_name) {
1103+ goto finally;
1104+ }
1105+
1106+ chk = PyString_AsString(uppercase_name);
1107+ while (*chk) {
1108+ if ((*chk >= '0' && *chk <= '9')
1109+ || (*chk >= 'A' && *chk <= 'Z')
1110+ || (*chk == '_'))
1111+ {
1112+ chk++;
1113+ } else {
1114+ PyErr_SetString(ProgrammingError, "invalid character in collation name");
1115+ goto finally;
1116+ }
1117+ }
1118+
1119+ if (callable != Py_None && !PyCallable_Check(callable)) {
1120+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
1121+ goto finally;
1122+ }
1123+
1124+ if (callable != Py_None) {
1125+ PyDict_SetItem(self->collations, uppercase_name, callable);
1126+ } else {
1127+ PyDict_DelItem(self->collations, uppercase_name);
1128+ }
1129+
1130+ rc = sqlite3_create_collation(self->db,
1131+ PyString_AsString(uppercase_name),
1132+ SQLITE_UTF8,
1133+ (callable != Py_None) ? callable : NULL,
1134+ (callable != Py_None) ? collation_callback : NULL);
1135+ if (rc != SQLITE_OK) {
1136+ PyDict_DelItem(self->collations, uppercase_name);
1137+ _seterror(self->db);
1138+ goto finally;
1139+ }
1140+
1141+finally:
1142+ Py_XDECREF(uppercase_name);
1143+
1144+ if (PyErr_Occurred()) {
1145+ retval = NULL;
1146+ } else {
1147+ Py_INCREF(Py_None);
1148+ retval = Py_None;
1149+ }
1150+
1151+ return retval;
1152+}
1153+
1154+static char connection_doc[] =
1155+PyDoc_STR("SQLite database connection object.");
1156+
1157+static PyGetSetDef connection_getset[] = {
1158+ {"isolation_level", (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
1159+ {"total_changes", (getter)connection_get_total_changes, (setter)0},
1160+ {NULL}
1161+};
1162+
1163+static PyMethodDef connection_methods[] = {
1164+ {"cursor", (PyCFunction)connection_cursor, METH_VARARGS|METH_KEYWORDS,
1165+ PyDoc_STR("Return a cursor for the connection.")},
1166+ {"close", (PyCFunction)connection_close, METH_NOARGS,
1167+ PyDoc_STR("Closes the connection.")},
1168+ {"commit", (PyCFunction)connection_commit, METH_NOARGS,
1169+ PyDoc_STR("Commit the current transaction.")},
1170+ {"rollback", (PyCFunction)connection_rollback, METH_NOARGS,
1171+ PyDoc_STR("Roll back the current transaction.")},
1172+ {"create_function", (PyCFunction)connection_create_function, METH_VARARGS|METH_KEYWORDS,
1173+ PyDoc_STR("Creates a new function. Non-standard.")},
1174+ {"create_aggregate", (PyCFunction)connection_create_aggregate, METH_VARARGS|METH_KEYWORDS,
1175+ PyDoc_STR("Creates a new aggregate. Non-standard.")},
1176+ {"set_authorizer", (PyCFunction)connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
1177+ PyDoc_STR("Sets authorizer callback. Non-standard.")},
1178+ {"execute", (PyCFunction)connection_execute, METH_VARARGS,
1179+ PyDoc_STR("Executes a SQL statement. Non-standard.")},
1180+ {"executemany", (PyCFunction)connection_executemany, METH_VARARGS,
1181+ PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")},
1182+ {"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
1183+ PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
1184+ {"create_collation", (PyCFunction)connection_create_collation, METH_VARARGS,
1185+ PyDoc_STR("Creates a collation function. Non-standard.")},
1186+ {"interrupt", (PyCFunction)connection_interrupt, METH_NOARGS,
1187+ PyDoc_STR("Abort any pending database operation. Non-standard.")},
1188+ {NULL, NULL}
1189+};
1190+
1191+static struct PyMemberDef connection_members[] =
1192+{
1193+ {"Warning", T_OBJECT, offsetof(Connection, Warning), RO},
1194+ {"Error", T_OBJECT, offsetof(Connection, Error), RO},
1195+ {"InterfaceError", T_OBJECT, offsetof(Connection, InterfaceError), RO},
1196+ {"DatabaseError", T_OBJECT, offsetof(Connection, DatabaseError), RO},
1197+ {"DataError", T_OBJECT, offsetof(Connection, DataError), RO},
1198+ {"OperationalError", T_OBJECT, offsetof(Connection, OperationalError), RO},
1199+ {"IntegrityError", T_OBJECT, offsetof(Connection, IntegrityError), RO},
1200+ {"InternalError", T_OBJECT, offsetof(Connection, InternalError), RO},
1201+ {"ProgrammingError", T_OBJECT, offsetof(Connection, ProgrammingError), RO},
1202+ {"NotSupportedError", T_OBJECT, offsetof(Connection, NotSupportedError), RO},
1203+ {"row_factory", T_OBJECT, offsetof(Connection, row_factory)},
1204+ {"text_factory", T_OBJECT, offsetof(Connection, text_factory)},
1205+ {NULL}
1206+};
1207+
1208+PyTypeObject ConnectionType = {
1209+ PyObject_HEAD_INIT(NULL)
1210+ 0, /* ob_size */
1211+ MODULE_NAME ".Connection", /* tp_name */
1212+ sizeof(Connection), /* tp_basicsize */
1213+ 0, /* tp_itemsize */
1214+ (destructor)connection_dealloc, /* tp_dealloc */
1215+ 0, /* tp_print */
1216+ 0, /* tp_getattr */
1217+ 0, /* tp_setattr */
1218+ 0, /* tp_compare */
1219+ 0, /* tp_repr */
1220+ 0, /* tp_as_number */
1221+ 0, /* tp_as_sequence */
1222+ 0, /* tp_as_mapping */
1223+ 0, /* tp_hash */
1224+ (ternaryfunc)connection_call, /* tp_call */
1225+ 0, /* tp_str */
1226+ 0, /* tp_getattro */
1227+ 0, /* tp_setattro */
1228+ 0, /* tp_as_buffer */
1229+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
1230+ connection_doc, /* tp_doc */
1231+ 0, /* tp_traverse */
1232+ 0, /* tp_clear */
1233+ 0, /* tp_richcompare */
1234+ 0, /* tp_weaklistoffset */
1235+ 0, /* tp_iter */
1236+ 0, /* tp_iternext */
1237+ connection_methods, /* tp_methods */
1238+ connection_members, /* tp_members */
1239+ connection_getset, /* tp_getset */
1240+ 0, /* tp_base */
1241+ 0, /* tp_dict */
1242+ 0, /* tp_descr_get */
1243+ 0, /* tp_descr_set */
1244+ 0, /* tp_dictoffset */
1245+ (initproc)connection_init, /* tp_init */
1246+ 0, /* tp_alloc */
1247+ 0, /* tp_new */
1248+ 0 /* tp_free */
1249+};
1250+
1251+extern int connection_setup_types(void)
1252+{
1253+ ConnectionType.tp_new = PyType_GenericNew;
1254+ return PyType_Ready(&ConnectionType);
1255+}
sys/src/cmd/python/Modules/_sqlite/connection.h+129−0
@@ -0,0 +1,129 @@
1+/* connection.h - definitions for the connection type
2+ *
3+ * Copyright (C) 2004-2006 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+
35+typedef struct
36+{
37+ PyObject_HEAD
38+ sqlite3* db;
39+
40+ /* 1 if we are currently within a transaction, i. e. if a BEGIN has been
41+ * issued */
42+ int inTransaction;
43+
44+ /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
45+ * bitwise combination thereof makes sense */
46+ int detect_types;
47+
48+ /* the timeout value in seconds for database locks */
49+ double timeout;
50+
51+ /* for internal use in the timeout handler: when did the timeout handler
52+ * first get called with count=0? */
53+ double timeout_started;
54+
55+ /* None for autocommit, otherwise a PyString with the isolation level */
56+ PyObject* isolation_level;
57+
58+ /* NULL for autocommit, otherwise a string with the BEGIN statment; will be
59+ * freed in connection destructor */
60+ char* begin_statement;
61+
62+ /* 1 if a check should be performed for each API call if the connection is
63+ * used from the same thread it was created in */
64+ int check_same_thread;
65+
66+ /* thread identification of the thread the connection was created in */
67+ long thread_ident;
68+
69+ Cache* statement_cache;
70+
71+ /* A list of weak references to statements used within this connection */
72+ PyObject* statements;
73+
74+ /* a counter for how many statements were created in the connection. May be
75+ * reset to 0 at certain intervals */
76+ int created_statements;
77+
78+ PyObject* row_factory;
79+
80+ /* Determines how bytestrings from SQLite are converted to Python objects:
81+ * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings
82+ * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created.
83+ * - PyString_Type: PyStrings are created as-is.
84+ * - Any custom callable: Any object returned from the callable called with the bytestring
85+ * as single parameter.
86+ */
87+ PyObject* text_factory;
88+
89+ /* remember references to functions/classes used in
90+ * create_function/create/aggregate, use these as dictionary keys, so we
91+ * can keep the total system refcount constant by clearing that dictionary
92+ * in connection_dealloc */
93+ PyObject* function_pinboard;
94+
95+ /* a dictionary of registered collation name => collation callable mappings */
96+ PyObject* collations;
97+
98+ /* Exception objects */
99+ PyObject* Warning;
100+ PyObject* Error;
101+ PyObject* InterfaceError;
102+ PyObject* DatabaseError;
103+ PyObject* DataError;
104+ PyObject* OperationalError;
105+ PyObject* IntegrityError;
106+ PyObject* InternalError;
107+ PyObject* ProgrammingError;
108+ PyObject* NotSupportedError;
109+} Connection;
110+
111+extern PyTypeObject ConnectionType;
112+
113+PyObject* connection_alloc(PyTypeObject* type, int aware);
114+void connection_dealloc(Connection* self);
115+PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
116+PyObject* connection_close(Connection* self, PyObject* args);
117+PyObject* _connection_begin(Connection* self);
118+PyObject* connection_begin(Connection* self, PyObject* args);
119+PyObject* connection_commit(Connection* self, PyObject* args);
120+PyObject* connection_rollback(Connection* self, PyObject* args);
121+PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
122+int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
123+
124+int check_thread(Connection* self);
125+int check_connection(Connection* con);
126+
127+int connection_setup_types(void);
128+
129+#endif
sys/src/cmd/python/Modules/_sqlite/cursor.c+1057−0
@@ -0,0 +1,1057 @@
1+/* cursor.c - the cursor type
2+ *
3+ * Copyright (C) 2004-2006 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 "cursor.h"
25+#include "module.h"
26+#include "util.h"
27+#include "sqlitecompat.h"
28+
29+/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
30+#ifndef INT32_MIN
31+#define INT32_MIN (-2147483647 - 1)
32+#endif
33+#ifndef INT32_MAX
34+#define INT32_MAX 2147483647
35+#endif
36+
37+PyObject* cursor_iternext(Cursor *self);
38+
39+static StatementKind detect_statement_type(char* statement)
40+{
41+ char buf[20];
42+ char* src;
43+ char* dst;
44+
45+ src = statement;
46+ /* skip over whitepace */
47+ while (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') {
48+ src++;
49+ }
50+
51+ if (*src == 0)
52+ return STATEMENT_INVALID;
53+
54+ dst = buf;
55+ *dst = 0;
56+ while (isalpha(*src) && dst - buf < sizeof(buf) - 2) {
57+ *dst++ = tolower(*src++);
58+ }
59+
60+ *dst = 0;
61+
62+ if (!strcmp(buf, "select")) {
63+ return STATEMENT_SELECT;
64+ } else if (!strcmp(buf, "insert")) {
65+ return STATEMENT_INSERT;
66+ } else if (!strcmp(buf, "update")) {
67+ return STATEMENT_UPDATE;
68+ } else if (!strcmp(buf, "delete")) {
69+ return STATEMENT_DELETE;
70+ } else if (!strcmp(buf, "replace")) {
71+ return STATEMENT_REPLACE;
72+ } else {
73+ return STATEMENT_OTHER;
74+ }
75+}
76+
77+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs)
78+{
79+ Connection* connection;
80+
81+ if (!PyArg_ParseTuple(args, "O!", &ConnectionType, &connection))
82+ {
83+ return -1;
84+ }
85+
86+ Py_INCREF(connection);
87+ self->connection = connection;
88+ self->statement = NULL;
89+ self->next_row = NULL;
90+
91+ self->row_cast_map = PyList_New(0);
92+ if (!self->row_cast_map) {
93+ return -1;
94+ }
95+
96+ Py_INCREF(Py_None);
97+ self->description = Py_None;
98+
99+ Py_INCREF(Py_None);
100+ self->lastrowid= Py_None;
101+
102+ self->arraysize = 1;
103+
104+ self->rowcount = PyInt_FromLong(-1L);
105+ if (!self->rowcount) {
106+ return -1;
107+ }
108+
109+ Py_INCREF(Py_None);
110+ self->row_factory = Py_None;
111+
112+ if (!check_thread(self->connection)) {
113+ return -1;
114+ }
115+
116+ return 0;
117+}
118+
119+void cursor_dealloc(Cursor* self)
120+{
121+ int rc;
122+
123+ /* Reset the statement if the user has not closed the cursor */
124+ if (self->statement) {
125+ rc = statement_reset(self->statement);
126+ Py_DECREF(self->statement);
127+ }
128+
129+ Py_XDECREF(self->connection);
130+ Py_XDECREF(self->row_cast_map);
131+ Py_XDECREF(self->description);
132+ Py_XDECREF(self->lastrowid);
133+ Py_XDECREF(self->rowcount);
134+ Py_XDECREF(self->row_factory);
135+ Py_XDECREF(self->next_row);
136+
137+ self->ob_type->tp_free((PyObject*)self);
138+}
139+
140+PyObject* _get_converter(PyObject* key)
141+{
142+ PyObject* upcase_key;
143+ PyObject* retval;
144+
145+ upcase_key = PyObject_CallMethod(key, "upper", "");
146+ if (!upcase_key) {
147+ return NULL;
148+ }
149+
150+ retval = PyDict_GetItem(converters, upcase_key);
151+ Py_DECREF(upcase_key);
152+
153+ return retval;
154+}
155+
156+int build_row_cast_map(Cursor* self)
157+{
158+ int i;
159+ const char* type_start = (const char*)-1;
160+ const char* pos;
161+
162+ const char* colname;
163+ const char* decltype;
164+ PyObject* py_decltype;
165+ PyObject* converter;
166+ PyObject* key;
167+
168+ if (!self->connection->detect_types) {
169+ return 0;
170+ }
171+
172+ Py_XDECREF(self->row_cast_map);
173+ self->row_cast_map = PyList_New(0);
174+
175+ for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
176+ converter = NULL;
177+
178+ if (self->connection->detect_types | PARSE_COLNAMES) {
179+ colname = sqlite3_column_name(self->statement->st, i);
180+ if (colname) {
181+ for (pos = colname; *pos != 0; pos++) {
182+ if (*pos == '[') {
183+ type_start = pos + 1;
184+ } else if (*pos == ']' && type_start != (const char*)-1) {
185+ key = PyString_FromStringAndSize(type_start, pos - type_start);
186+ if (!key) {
187+ /* creating a string failed, but it is too complicated
188+ * to propagate the error here, we just assume there is
189+ * no converter and proceed */
190+ break;
191+ }
192+
193+ converter = _get_converter(key);
194+ Py_DECREF(key);
195+ break;
196+ }
197+ }
198+ }
199+ }
200+
201+ if (!converter && self->connection->detect_types | PARSE_DECLTYPES) {
202+ decltype = sqlite3_column_decltype(self->statement->st, i);
203+ if (decltype) {
204+ for (pos = decltype;;pos++) {
205+ if (*pos == ' ' || *pos == 0) {
206+ py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
207+ if (!py_decltype) {
208+ return -1;
209+ }
210+ break;
211+ }
212+ }
213+
214+ converter = _get_converter(py_decltype);
215+ Py_DECREF(py_decltype);
216+ }
217+ }
218+
219+ if (!converter) {
220+ converter = Py_None;
221+ }
222+
223+ if (PyList_Append(self->row_cast_map, converter) != 0) {
224+ if (converter != Py_None) {
225+ Py_DECREF(converter);
226+ }
227+ Py_XDECREF(self->row_cast_map);
228+ self->row_cast_map = NULL;
229+
230+ return -1;
231+ }
232+ }
233+
234+ return 0;
235+}
236+
237+PyObject* _build_column_name(const char* colname)
238+{
239+ const char* pos;
240+
241+ if (!colname) {
242+ Py_INCREF(Py_None);
243+ return Py_None;
244+ }
245+
246+ for (pos = colname;; pos++) {
247+ if (*pos == 0 || *pos == '[') {
248+ if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) {
249+ pos--;
250+ }
251+ return PyString_FromStringAndSize(colname, pos - colname);
252+ }
253+ }
254+}
255+
256+PyObject* unicode_from_string(const char* val_str, int optimize)
257+{
258+ const char* check;
259+ int is_ascii = 0;
260+
261+ if (optimize) {
262+ is_ascii = 1;
263+
264+ check = val_str;
265+ while (*check) {
266+ if (*check & 0x80) {
267+ is_ascii = 0;
268+ break;
269+ }
270+
271+ check++;
272+ }
273+ }
274+
275+ if (is_ascii) {
276+ return PyString_FromString(val_str);
277+ } else {
278+ return PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
279+ }
280+}
281+
282+/*
283+ * Returns a row from the currently active SQLite statement
284+ *
285+ * Precondidition:
286+ * - sqlite3_step() has been called before and it returned SQLITE_ROW.
287+ */
288+PyObject* _fetch_one_row(Cursor* self)
289+{
290+ int i, numcols;
291+ PyObject* row;
292+ PyObject* item = NULL;
293+ int coltype;
294+ PY_LONG_LONG intval;
295+ PyObject* converter;
296+ PyObject* converted;
297+ Py_ssize_t nbytes;
298+ PyObject* buffer;
299+ void* raw_buffer;
300+ const char* val_str;
301+ char buf[200];
302+ const char* colname;
303+
304+ Py_BEGIN_ALLOW_THREADS
305+ numcols = sqlite3_data_count(self->statement->st);
306+ Py_END_ALLOW_THREADS
307+
308+ row = PyTuple_New(numcols);
309+ if (!row) {
310+ return NULL;
311+ }
312+
313+ for (i = 0; i < numcols; i++) {
314+ if (self->connection->detect_types) {
315+ converter = PyList_GetItem(self->row_cast_map, i);
316+ if (!converter) {
317+ converter = Py_None;
318+ }
319+ } else {
320+ converter = Py_None;
321+ }
322+
323+ if (converter != Py_None) {
324+ nbytes = sqlite3_column_bytes(self->statement->st, i);
325+ val_str = (const char*)sqlite3_column_blob(self->statement->st, i);
326+ if (!val_str) {
327+ Py_INCREF(Py_None);
328+ converted = Py_None;
329+ } else {
330+ item = PyString_FromStringAndSize(val_str, nbytes);
331+ if (!item) {
332+ return NULL;
333+ }
334+ converted = PyObject_CallFunction(converter, "O", item);
335+ Py_DECREF(item);
336+ if (!converted) {
337+ break;
338+ }
339+ }
340+ } else {
341+ Py_BEGIN_ALLOW_THREADS
342+ coltype = sqlite3_column_type(self->statement->st, i);
343+ Py_END_ALLOW_THREADS
344+ if (coltype == SQLITE_NULL) {
345+ Py_INCREF(Py_None);
346+ converted = Py_None;
347+ } else if (coltype == SQLITE_INTEGER) {
348+ intval = sqlite3_column_int64(self->statement->st, i);
349+ if (intval < INT32_MIN || intval > INT32_MAX) {
350+ converted = PyLong_FromLongLong(intval);
351+ } else {
352+ converted = PyInt_FromLong((long)intval);
353+ }
354+ } else if (coltype == SQLITE_FLOAT) {
355+ converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
356+ } else if (coltype == SQLITE_TEXT) {
357+ val_str = (const char*)sqlite3_column_text(self->statement->st, i);
358+ if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
359+ || (self->connection->text_factory == OptimizedUnicode)) {
360+
361+ converted = unicode_from_string(val_str,
362+ self->connection->text_factory == OptimizedUnicode ? 1 : 0);
363+
364+ if (!converted) {
365+ colname = sqlite3_column_name(self->statement->st, i);
366+ if (!colname) {
367+ colname = "<unknown column name>";
368+ }
369+ PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
370+ colname , val_str);
371+ PyErr_SetString(OperationalError, buf);
372+ }
373+ } else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
374+ converted = PyString_FromString(val_str);
375+ } else {
376+ converted = PyObject_CallFunction(self->connection->text_factory, "s", val_str);
377+ }
378+ } else {
379+ /* coltype == SQLITE_BLOB */
380+ nbytes = sqlite3_column_bytes(self->statement->st, i);
381+ buffer = PyBuffer_New(nbytes);
382+ if (!buffer) {
383+ break;
384+ }
385+ if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) {
386+ break;
387+ }
388+ memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes);
389+ converted = buffer;
390+ }
391+ }
392+
393+ if (converted) {
394+ PyTuple_SetItem(row, i, converted);
395+ } else {
396+ Py_INCREF(Py_None);
397+ PyTuple_SetItem(row, i, Py_None);
398+ }
399+ }
400+
401+ if (PyErr_Occurred()) {
402+ Py_DECREF(row);
403+ row = NULL;
404+ }
405+
406+ return row;
407+}
408+
409+PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
410+{
411+ PyObject* operation;
412+ PyObject* operation_bytestr = NULL;
413+ char* operation_cstr;
414+ PyObject* parameters_list = NULL;
415+ PyObject* parameters_iter = NULL;
416+ PyObject* parameters = NULL;
417+ int i;
418+ int rc;
419+ PyObject* func_args;
420+ PyObject* result;
421+ int numcols;
422+ PY_LONG_LONG lastrowid;
423+ int statement_type;
424+ PyObject* descriptor;
425+ PyObject* second_argument = NULL;
426+ long rowcount = 0;
427+
428+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
429+ return NULL;
430+ }
431+
432+ Py_XDECREF(self->next_row);
433+ self->next_row = NULL;
434+
435+ if (multiple) {
436+ /* executemany() */
437+ if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
438+ return NULL;
439+ }
440+
441+ if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
442+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
443+ return NULL;
444+ }
445+
446+ if (PyIter_Check(second_argument)) {
447+ /* iterator */
448+ Py_INCREF(second_argument);
449+ parameters_iter = second_argument;
450+ } else {
451+ /* sequence */
452+ parameters_iter = PyObject_GetIter(second_argument);
453+ if (!parameters_iter) {
454+ return NULL;
455+ }
456+ }
457+ } else {
458+ /* execute() */
459+ if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
460+ return NULL;
461+ }
462+
463+ if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
464+ PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
465+ return NULL;
466+ }
467+
468+ parameters_list = PyList_New(0);
469+ if (!parameters_list) {
470+ return NULL;
471+ }
472+
473+ if (second_argument == NULL) {
474+ second_argument = PyTuple_New(0);
475+ if (!second_argument) {
476+ goto error;
477+ }
478+ } else {
479+ Py_INCREF(second_argument);
480+ }
481+ if (PyList_Append(parameters_list, second_argument) != 0) {
482+ Py_DECREF(second_argument);
483+ goto error;
484+ }
485+ Py_DECREF(second_argument);
486+
487+ parameters_iter = PyObject_GetIter(parameters_list);
488+ if (!parameters_iter) {
489+ goto error;
490+ }
491+ }
492+
493+ if (self->statement != NULL) {
494+ /* There is an active statement */
495+ rc = statement_reset(self->statement);
496+ }
497+
498+ if (PyString_Check(operation)) {
499+ operation_cstr = PyString_AsString(operation);
500+ } else {
501+ operation_bytestr = PyUnicode_AsUTF8String(operation);
502+ if (!operation_bytestr) {
503+ goto error;
504+ }
505+
506+ operation_cstr = PyString_AsString(operation_bytestr);
507+ }
508+
509+ /* reset description and rowcount */
510+ Py_DECREF(self->description);
511+ Py_INCREF(Py_None);
512+ self->description = Py_None;
513+
514+ Py_DECREF(self->rowcount);
515+ self->rowcount = PyInt_FromLong(-1L);
516+ if (!self->rowcount) {
517+ goto error;
518+ }
519+
520+ statement_type = detect_statement_type(operation_cstr);
521+ if (self->connection->begin_statement) {
522+ switch (statement_type) {
523+ case STATEMENT_UPDATE:
524+ case STATEMENT_DELETE:
525+ case STATEMENT_INSERT:
526+ case STATEMENT_REPLACE:
527+ if (!self->connection->inTransaction) {
528+ result = _connection_begin(self->connection);
529+ if (!result) {
530+ goto error;
531+ }
532+ Py_DECREF(result);
533+ }
534+ break;
535+ case STATEMENT_OTHER:
536+ /* it's a DDL statement or something similar
537+ - we better COMMIT first so it works for all cases */
538+ if (self->connection->inTransaction) {
539+ result = connection_commit(self->connection, NULL);
540+ if (!result) {
541+ goto error;
542+ }
543+ Py_DECREF(result);
544+ }
545+ break;
546+ case STATEMENT_SELECT:
547+ if (multiple) {
548+ PyErr_SetString(ProgrammingError,
549+ "You cannot execute SELECT statements in executemany().");
550+ goto error;
551+ }
552+ break;
553+ }
554+ }
555+
556+ func_args = PyTuple_New(1);
557+ if (!func_args) {
558+ goto error;
559+ }
560+ Py_INCREF(operation);
561+ if (PyTuple_SetItem(func_args, 0, operation) != 0) {
562+ goto error;
563+ }
564+
565+ if (self->statement) {
566+ (void)statement_reset(self->statement);
567+ Py_DECREF(self->statement);
568+ }
569+
570+ self->statement = (Statement*)cache_get(self->connection->statement_cache, func_args);
571+ Py_DECREF(func_args);
572+
573+ if (!self->statement) {
574+ goto error;
575+ }
576+
577+ if (self->statement->in_use) {
578+ Py_DECREF(self->statement);
579+ self->statement = PyObject_New(Statement, &StatementType);
580+ if (!self->statement) {
581+ goto error;
582+ }
583+ rc = statement_create(self->statement, self->connection, operation);
584+ if (rc != SQLITE_OK) {
585+ self->statement = 0;
586+ goto error;
587+ }
588+ }
589+
590+ statement_reset(self->statement);
591+ statement_mark_dirty(self->statement);
592+
593+ while (1) {
594+ parameters = PyIter_Next(parameters_iter);
595+ if (!parameters) {
596+ break;
597+ }
598+
599+ statement_mark_dirty(self->statement);
600+
601+ statement_bind_parameters(self->statement, parameters);
602+ if (PyErr_Occurred()) {
603+ goto error;
604+ }
605+
606+ if (build_row_cast_map(self) != 0) {
607+ PyErr_SetString(OperationalError, "Error while building row_cast_map");
608+ goto error;
609+ }
610+
611+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
612+ if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
613+ rc = statement_reset(self->statement);
614+ if (rc == SQLITE_SCHEMA) {
615+ rc = statement_recompile(self->statement, parameters);
616+ if (rc == SQLITE_OK) {
617+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
618+ } else {
619+ _seterror(self->connection->db);
620+ goto error;
621+ }
622+ } else {
623+ if (PyErr_Occurred()) {
624+ /* there was an error that occurred in a user-defined callback */
625+ if (_enable_callback_tracebacks) {
626+ PyErr_Print();
627+ } else {
628+ PyErr_Clear();
629+ }
630+ }
631+ _seterror(self->connection->db);
632+ goto error;
633+ }
634+ }
635+
636+ if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
637+ Py_BEGIN_ALLOW_THREADS
638+ numcols = sqlite3_column_count(self->statement->st);
639+ Py_END_ALLOW_THREADS
640+
641+ if (self->description == Py_None) {
642+ Py_DECREF(self->description);
643+ self->description = PyTuple_New(numcols);
644+ if (!self->description) {
645+ goto error;
646+ }
647+ for (i = 0; i < numcols; i++) {
648+ descriptor = PyTuple_New(7);
649+ if (!descriptor) {
650+ goto error;
651+ }
652+ PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i)));
653+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
654+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
655+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
656+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
657+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
658+ Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
659+ PyTuple_SetItem(self->description, i, descriptor);
660+ }
661+ }
662+ }
663+
664+ if (rc == SQLITE_ROW) {
665+ if (multiple) {
666+ PyErr_SetString(ProgrammingError, "executemany() can only execute DML statements.");
667+ goto error;
668+ }
669+
670+ self->next_row = _fetch_one_row(self);
671+ } else if (rc == SQLITE_DONE && !multiple) {
672+ statement_reset(self->statement);
673+ Py_DECREF(self->statement);
674+ self->statement = 0;
675+ }
676+
677+ switch (statement_type) {
678+ case STATEMENT_UPDATE:
679+ case STATEMENT_DELETE:
680+ case STATEMENT_INSERT:
681+ case STATEMENT_REPLACE:
682+ Py_BEGIN_ALLOW_THREADS
683+ rowcount += (long)sqlite3_changes(self->connection->db);
684+ Py_END_ALLOW_THREADS
685+ Py_DECREF(self->rowcount);
686+ self->rowcount = PyInt_FromLong(rowcount);
687+ }
688+
689+ Py_DECREF(self->lastrowid);
690+ if (statement_type == STATEMENT_INSERT) {
691+ Py_BEGIN_ALLOW_THREADS
692+ lastrowid = sqlite3_last_insert_rowid(self->connection->db);
693+ Py_END_ALLOW_THREADS
694+ self->lastrowid = PyInt_FromLong((long)lastrowid);
695+ } else {
696+ Py_INCREF(Py_None);
697+ self->lastrowid = Py_None;
698+ }
699+
700+ if (multiple) {
701+ rc = statement_reset(self->statement);
702+ }
703+ Py_XDECREF(parameters);
704+ }
705+
706+error:
707+ Py_XDECREF(operation_bytestr);
708+ Py_XDECREF(parameters);
709+ Py_XDECREF(parameters_iter);
710+ Py_XDECREF(parameters_list);
711+
712+ if (PyErr_Occurred()) {
713+ return NULL;
714+ } else {
715+ Py_INCREF(self);
716+ return (PyObject*)self;
717+ }
718+}
719+
720+PyObject* cursor_execute(Cursor* self, PyObject* args)
721+{
722+ return _query_execute(self, 0, args);
723+}
724+
725+PyObject* cursor_executemany(Cursor* self, PyObject* args)
726+{
727+ return _query_execute(self, 1, args);
728+}
729+
730+PyObject* cursor_executescript(Cursor* self, PyObject* args)
731+{
732+ PyObject* script_obj;
733+ PyObject* script_str = NULL;
734+ const char* script_cstr;
735+ sqlite3_stmt* statement;
736+ int rc;
737+ PyObject* result;
738+ int statement_completed = 0;
739+
740+ if (!PyArg_ParseTuple(args, "O", &script_obj)) {
741+ return NULL;
742+ }
743+
744+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
745+ return NULL;
746+ }
747+
748+ if (PyString_Check(script_obj)) {
749+ script_cstr = PyString_AsString(script_obj);
750+ } else if (PyUnicode_Check(script_obj)) {
751+ script_str = PyUnicode_AsUTF8String(script_obj);
752+ if (!script_str) {
753+ return NULL;
754+ }
755+
756+ script_cstr = PyString_AsString(script_str);
757+ } else {
758+ PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string.");
759+ return NULL;
760+ }
761+
762+ /* commit first */
763+ result = connection_commit(self->connection, NULL);
764+ if (!result) {
765+ goto error;
766+ }
767+ Py_DECREF(result);
768+
769+ while (1) {
770+ if (!sqlite3_complete(script_cstr)) {
771+ break;
772+ }
773+ statement_completed = 1;
774+
775+ rc = sqlite3_prepare(self->connection->db,
776+ script_cstr,
777+ -1,
778+ &statement,
779+ &script_cstr);
780+ if (rc != SQLITE_OK) {
781+ _seterror(self->connection->db);
782+ goto error;
783+ }
784+
785+ /* execute statement, and ignore results of SELECT statements */
786+ rc = SQLITE_ROW;
787+ while (rc == SQLITE_ROW) {
788+ rc = _sqlite_step_with_busyhandler(statement, self->connection);
789+ }
790+
791+ if (rc != SQLITE_DONE) {
792+ (void)sqlite3_finalize(statement);
793+ _seterror(self->connection->db);
794+ goto error;
795+ }
796+
797+ rc = sqlite3_finalize(statement);
798+ if (rc != SQLITE_OK) {
799+ _seterror(self->connection->db);
800+ goto error;
801+ }
802+ }
803+
804+error:
805+ Py_XDECREF(script_str);
806+
807+ if (!statement_completed) {
808+ PyErr_SetString(ProgrammingError, "you did not provide a complete SQL statement");
809+ }
810+
811+ if (PyErr_Occurred()) {
812+ return NULL;
813+ } else {
814+ Py_INCREF(self);
815+ return (PyObject*)self;
816+ }
817+}
818+
819+PyObject* cursor_getiter(Cursor *self)
820+{
821+ Py_INCREF(self);
822+ return (PyObject*)self;
823+}
824+
825+PyObject* cursor_iternext(Cursor *self)
826+{
827+ PyObject* next_row_tuple;
828+ PyObject* next_row;
829+ int rc;
830+
831+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
832+ return NULL;
833+ }
834+
835+ if (!self->next_row) {
836+ if (self->statement) {
837+ (void)statement_reset(self->statement);
838+ Py_DECREF(self->statement);
839+ self->statement = NULL;
840+ }
841+ return NULL;
842+ }
843+
844+ next_row_tuple = self->next_row;
845+ self->next_row = NULL;
846+
847+ if (self->row_factory != Py_None) {
848+ next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple);
849+ Py_DECREF(next_row_tuple);
850+ } else {
851+ next_row = next_row_tuple;
852+ }
853+
854+ rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
855+ if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
856+ Py_DECREF(next_row);
857+ _seterror(self->connection->db);
858+ return NULL;
859+ }
860+
861+ if (rc == SQLITE_ROW) {
862+ self->next_row = _fetch_one_row(self);
863+ }
864+
865+ return next_row;
866+}
867+
868+PyObject* cursor_fetchone(Cursor* self, PyObject* args)
869+{
870+ PyObject* row;
871+
872+ row = cursor_iternext(self);
873+ if (!row && !PyErr_Occurred()) {
874+ Py_INCREF(Py_None);
875+ return Py_None;
876+ }
877+
878+ return row;
879+}
880+
881+PyObject* cursor_fetchmany(Cursor* self, PyObject* args)
882+{
883+ PyObject* row;
884+ PyObject* list;
885+ int maxrows = self->arraysize;
886+ int counter = 0;
887+
888+ if (!PyArg_ParseTuple(args, "|i", &maxrows)) {
889+ return NULL;
890+ }
891+
892+ list = PyList_New(0);
893+ if (!list) {
894+ return NULL;
895+ }
896+
897+ /* just make sure we enter the loop */
898+ row = Py_None;
899+
900+ while (row) {
901+ row = cursor_iternext(self);
902+ if (row) {
903+ PyList_Append(list, row);
904+ Py_DECREF(row);
905+ } else {
906+ break;
907+ }
908+
909+ if (++counter == maxrows) {
910+ break;
911+ }
912+ }
913+
914+ if (PyErr_Occurred()) {
915+ Py_DECREF(list);
916+ return NULL;
917+ } else {
918+ return list;
919+ }
920+}
921+
922+PyObject* cursor_fetchall(Cursor* self, PyObject* args)
923+{
924+ PyObject* row;
925+ PyObject* list;
926+
927+ list = PyList_New(0);
928+ if (!list) {
929+ return NULL;
930+ }
931+
932+ /* just make sure we enter the loop */
933+ row = (PyObject*)Py_None;
934+
935+ while (row) {
936+ row = cursor_iternext(self);
937+ if (row) {
938+ PyList_Append(list, row);
939+ Py_DECREF(row);
940+ }
941+ }
942+
943+ if (PyErr_Occurred()) {
944+ Py_DECREF(list);
945+ return NULL;
946+ } else {
947+ return list;
948+ }
949+}
950+
951+PyObject* pysqlite_noop(Connection* self, PyObject* args)
952+{
953+ /* don't care, return None */
954+ Py_INCREF(Py_None);
955+ return Py_None;
956+}
957+
958+PyObject* cursor_close(Cursor* self, PyObject* args)
959+{
960+ if (!check_thread(self->connection) || !check_connection(self->connection)) {
961+ return NULL;
962+ }
963+
964+ if (self->statement) {
965+ (void)statement_reset(self->statement);
966+ Py_DECREF(self->statement);
967+ self->statement = 0;
968+ }
969+
970+ Py_INCREF(Py_None);
971+ return Py_None;
972+}
973+
974+static PyMethodDef cursor_methods[] = {
975+ {"execute", (PyCFunction)cursor_execute, METH_VARARGS,
976+ PyDoc_STR("Executes a SQL statement.")},
977+ {"executemany", (PyCFunction)cursor_executemany, METH_VARARGS,
978+ PyDoc_STR("Repeatedly executes a SQL statement.")},
979+ {"executescript", (PyCFunction)cursor_executescript, METH_VARARGS,
980+ PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
981+ {"fetchone", (PyCFunction)cursor_fetchone, METH_NOARGS,
982+ PyDoc_STR("Fetches several rows from the resultset.")},
983+ {"fetchmany", (PyCFunction)cursor_fetchmany, METH_VARARGS,
984+ PyDoc_STR("Fetches all rows from the resultset.")},
985+ {"fetchall", (PyCFunction)cursor_fetchall, METH_NOARGS,
986+ PyDoc_STR("Fetches one row from the resultset.")},
987+ {"close", (PyCFunction)cursor_close, METH_NOARGS,
988+ PyDoc_STR("Closes the cursor.")},
989+ {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS,
990+ PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
991+ {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS,
992+ PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
993+ {NULL, NULL}
994+};
995+
996+static struct PyMemberDef cursor_members[] =
997+{
998+ {"connection", T_OBJECT, offsetof(Cursor, connection), RO},
999+ {"description", T_OBJECT, offsetof(Cursor, description), RO},
1000+ {"arraysize", T_INT, offsetof(Cursor, arraysize), 0},
1001+ {"lastrowid", T_OBJECT, offsetof(Cursor, lastrowid), RO},
1002+ {"rowcount", T_OBJECT, offsetof(Cursor, rowcount), RO},
1003+ {"row_factory", T_OBJECT, offsetof(Cursor, row_factory), 0},
1004+ {NULL}
1005+};
1006+
1007+static char cursor_doc[] =
1008+PyDoc_STR("SQLite database cursor class.");
1009+
1010+PyTypeObject CursorType = {
1011+ PyObject_HEAD_INIT(NULL)
1012+ 0, /* ob_size */
1013+ MODULE_NAME ".Cursor", /* tp_name */
1014+ sizeof(Cursor), /* tp_basicsize */
1015+ 0, /* tp_itemsize */
1016+ (destructor)cursor_dealloc, /* tp_dealloc */
1017+ 0, /* tp_print */
1018+ 0, /* tp_getattr */
1019+ 0, /* tp_setattr */
1020+ 0, /* tp_compare */
1021+ 0, /* tp_repr */
1022+ 0, /* tp_as_number */
1023+ 0, /* tp_as_sequence */
1024+ 0, /* tp_as_mapping */
1025+ 0, /* tp_hash */
1026+ 0, /* tp_call */
1027+ 0, /* tp_str */
1028+ 0, /* tp_getattro */
1029+ 0, /* tp_setattro */
1030+ 0, /* tp_as_buffer */
1031+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
1032+ cursor_doc, /* tp_doc */
1033+ 0, /* tp_traverse */
1034+ 0, /* tp_clear */
1035+ 0, /* tp_richcompare */
1036+ 0, /* tp_weaklistoffset */
1037+ (getiterfunc)cursor_getiter, /* tp_iter */
1038+ (iternextfunc)cursor_iternext, /* tp_iternext */
1039+ cursor_methods, /* tp_methods */
1040+ cursor_members, /* tp_members */
1041+ 0, /* tp_getset */
1042+ 0, /* tp_base */
1043+ 0, /* tp_dict */
1044+ 0, /* tp_descr_get */
1045+ 0, /* tp_descr_set */
1046+ 0, /* tp_dictoffset */
1047+ (initproc)cursor_init, /* tp_init */
1048+ 0, /* tp_alloc */
1049+ 0, /* tp_new */
1050+ 0 /* tp_free */
1051+};
1052+
1053+extern int cursor_setup_types(void)
1054+{
1055+ CursorType.tp_new = PyType_GenericNew;
1056+ return PyType_Ready(&CursorType);
1057+}
sys/src/cmd/python/Modules/_sqlite/cursor.h+71−0
@@ -0,0 +1,71 @@
1+/* cursor.h - definitions for the cursor type
2+ *
3+ * Copyright (C) 2004-2006 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+ Connection* connection;
36+ PyObject* description;
37+ PyObject* row_cast_map;
38+ int arraysize;
39+ PyObject* lastrowid;
40+ PyObject* rowcount;
41+ PyObject* row_factory;
42+ Statement* statement;
43+
44+ /* the next row to be returned, NULL if no next row available */
45+ PyObject* next_row;
46+} Cursor;
47+
48+typedef enum {
49+ STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
50+ STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
51+ STATEMENT_OTHER
52+} StatementKind;
53+
54+extern PyTypeObject CursorType;
55+
56+int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
57+void cursor_dealloc(Cursor* self);
58+PyObject* cursor_execute(Cursor* self, PyObject* args);
59+PyObject* cursor_executemany(Cursor* self, PyObject* args);
60+PyObject* cursor_getiter(Cursor *self);
61+PyObject* cursor_iternext(Cursor *self);
62+PyObject* cursor_fetchone(Cursor* self, PyObject* args);
63+PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
64+PyObject* cursor_fetchall(Cursor* self, PyObject* args);
65+PyObject* pysqlite_noop(Connection* self, PyObject* args);
66+PyObject* cursor_close(Cursor* self, PyObject* args);
67+
68+int cursor_setup_types(void);
69+
70+#define UNKNOWN (-1)
71+#endif
sys/src/cmd/python/Modules/_sqlite/microprotocols.c+142−0
@@ -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+/* microprotocols_init - initialize the adapters dictionary */
39+
40+int
41+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+/* microprotocols_add - add a reverse type-caster to the dictionary */
53+
54+int
55+microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
56+{
57+ PyObject* key;
58+ int rc;
59+
60+ if (proto == NULL) proto = (PyObject*)&SQLitePrepareProtocolType;
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+/* microprotocols_adapt - adapt an object to the built-in protocol */
74+
75+PyObject *
76+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 SQLitePrepareProtocolType 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(ProgrammingError, "can't adapt");
129+ return NULL;
130+}
131+
132+/** module-level functions **/
133+
134+PyObject *
135+psyco_microprotocols_adapt(Cursor *self, PyObject *args)
136+{
137+ PyObject *obj, *alt = NULL;
138+ PyObject *proto = (PyObject*)&SQLitePrepareProtocolType;
139+
140+ if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
141+ return microprotocols_adapt(obj, proto, alt);
142+}
sys/src/cmd/python/Modules/_sqlite/microprotocols.h+59−0
@@ -0,0 +1,59 @@
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+#ifdef __cplusplus
32+extern "C" {
33+#endif
34+
35+/** adapters registry **/
36+
37+extern PyObject *psyco_adapters;
38+
39+/** the names of the three mandatory methods **/
40+
41+#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
42+#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
43+#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
44+
45+/** exported functions **/
46+
47+/* used by module.c to init the microprotocols system */
48+extern int microprotocols_init(PyObject *dict);
49+extern int microprotocols_add(
50+ PyTypeObject *type, PyObject *proto, PyObject *cast);
51+extern PyObject *microprotocols_adapt(
52+ PyObject *obj, PyObject *proto, PyObject *alt);
53+
54+extern PyObject *
55+ psyco_microprotocols_adapt(Cursor* self, PyObject *args);
56+#define psyco_microprotocols_adapt_doc \
57+ "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard."
58+
59+#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */
sys/src/cmd/python/Modules/_sqlite/module.c+409−0
@@ -0,0 +1,409 @@
1+ /* module.c - the module itself
2+ *
3+ * Copyright (C) 2004-2006 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 "connection.h"
25+#include "statement.h"
26+#include "cursor.h"
27+#include "cache.h"
28+#include "prepare_protocol.h"
29+#include "microprotocols.h"
30+#include "row.h"
31+
32+#if SQLITE_VERSION_NUMBER >= 3003003
33+#define HAVE_SHARED_CACHE
34+#endif
35+
36+/* static objects at module-level */
37+
38+PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
39+ *OperationalError, *ProgrammingError, *IntegrityError, *DataError,
40+ *NotSupportedError, *OptimizedUnicode;
41+
42+PyObject* converters;
43+int _enable_callback_tracebacks;
44+
45+static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
46+ kwargs)
47+{
48+ /* Python seems to have no way of extracting a single keyword-arg at
49+ * C-level, so this code is redundant with the one in connection_init in
50+ * connection.c and must always be copied from there ... */
51+
52+ static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
53+ char* database;
54+ int detect_types = 0;
55+ PyObject* isolation_level;
56+ PyObject* factory = NULL;
57+ int check_same_thread = 1;
58+ int cached_statements;
59+ double timeout = 5.0;
60+
61+ PyObject* result;
62+
63+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
64+ &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
65+ {
66+ return NULL;
67+ }
68+
69+ if (factory == NULL) {
70+ factory = (PyObject*)&ConnectionType;
71+ }
72+
73+ result = PyObject_Call(factory, args, kwargs);
74+
75+ return result;
76+}
77+
78+static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
79+ kwargs)
80+{
81+ static char *kwlist[] = {"statement", NULL, NULL};
82+ char* statement;
83+
84+ PyObject* result;
85+
86+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
87+ {
88+ return NULL;
89+ }
90+
91+ if (sqlite3_complete(statement)) {
92+ result = Py_True;
93+ } else {
94+ result = Py_False;
95+ }
96+
97+ Py_INCREF(result);
98+
99+ return result;
100+}
101+
102+#ifdef HAVE_SHARED_CACHE
103+static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
104+ kwargs)
105+{
106+ static char *kwlist[] = {"do_enable", NULL, NULL};
107+ int do_enable;
108+ int rc;
109+
110+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
111+ {
112+ return NULL;
113+ }
114+
115+ rc = sqlite3_enable_shared_cache(do_enable);
116+
117+ if (rc != SQLITE_OK) {
118+ PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
119+ return NULL;
120+ } else {
121+ Py_INCREF(Py_None);
122+ return Py_None;
123+ }
124+}
125+#endif /* HAVE_SHARED_CACHE */
126+
127+static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
128+{
129+ PyTypeObject* type;
130+ PyObject* caster;
131+
132+ if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
133+ return NULL;
134+ }
135+
136+ microprotocols_add(type, (PyObject*)&SQLitePrepareProtocolType, caster);
137+
138+ Py_INCREF(Py_None);
139+ return Py_None;
140+}
141+
142+static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
143+{
144+ char* orig_name;
145+ char* name = NULL;
146+ char* c;
147+ PyObject* callable;
148+ PyObject* retval = NULL;
149+
150+ if (!PyArg_ParseTuple(args, "sO", &orig_name, &callable)) {
151+ return NULL;
152+ }
153+
154+ /* convert the name to lowercase */
155+ name = PyMem_Malloc(strlen(orig_name) + 2);
156+ if (!name) {
157+ goto error;
158+ }
159+ strcpy(name, orig_name);
160+ for (c = name; *c != (char)0; c++) {
161+ *c = (*c) & 0xDF;
162+ }
163+
164+ if (PyDict_SetItemString(converters, name, callable) != 0) {
165+ goto error;
166+ }
167+
168+ Py_INCREF(Py_None);
169+ retval = Py_None;
170+error:
171+ if (name) {
172+ PyMem_Free(name);
173+ }
174+ return retval;
175+}
176+
177+static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyObject* kwargs)
178+{
179+ if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
180+ return NULL;
181+ }
182+
183+ Py_INCREF(Py_None);
184+ return Py_None;
185+}
186+
187+void converters_init(PyObject* dict)
188+{
189+ converters = PyDict_New();
190+ if (!converters) {
191+ return;
192+ }
193+
194+ PyDict_SetItemString(dict, "converters", converters);
195+}
196+
197+static PyMethodDef module_methods[] = {
198+ {"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
199+ {"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
200+#ifdef HAVE_SHARED_CACHE
201+ {"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread. Experimental/Non-standard.")},
202+#endif
203+ {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
204+ {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
205+ {"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
206+ {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, METH_VARARGS, PyDoc_STR("Enable or disable callback functions throwing errors to stderr.")},
207+ {NULL, NULL}
208+};
209+
210+struct _IntConstantPair {
211+ char* constant_name;
212+ int constant_value;
213+};
214+
215+typedef struct _IntConstantPair IntConstantPair;
216+
217+static IntConstantPair _int_constants[] = {
218+ {"PARSE_DECLTYPES", PARSE_DECLTYPES},
219+ {"PARSE_COLNAMES", PARSE_COLNAMES},
220+
221+ {"SQLITE_OK", SQLITE_OK},
222+ {"SQLITE_DENY", SQLITE_DENY},
223+ {"SQLITE_IGNORE", SQLITE_IGNORE},
224+ {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX},
225+ {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE},
226+ {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX},
227+ {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE},
228+ {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER},
229+ {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW},
230+ {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER},
231+ {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW},
232+ {"SQLITE_DELETE", SQLITE_DELETE},
233+ {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX},
234+ {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE},
235+ {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX},
236+ {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE},
237+ {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER},
238+ {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW},
239+ {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER},
240+ {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW},
241+ {"SQLITE_INSERT", SQLITE_INSERT},
242+ {"SQLITE_PRAGMA", SQLITE_PRAGMA},
243+ {"SQLITE_READ", SQLITE_READ},
244+ {"SQLITE_SELECT", SQLITE_SELECT},
245+ {"SQLITE_TRANSACTION", SQLITE_TRANSACTION},
246+ {"SQLITE_UPDATE", SQLITE_UPDATE},
247+ {"SQLITE_ATTACH", SQLITE_ATTACH},
248+ {"SQLITE_DETACH", SQLITE_DETACH},
249+#if SQLITE_VERSION_NUMBER >= 3002001
250+ {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE},
251+ {"SQLITE_REINDEX", SQLITE_REINDEX},
252+#endif
253+#if SQLITE_VERSION_NUMBER >= 3003000
254+ {"SQLITE_ANALYZE", SQLITE_ANALYZE},
255+#endif
256+ {(char*)NULL, 0}
257+};
258+
259+PyMODINIT_FUNC init_sqlite3(void)
260+{
261+ PyObject *module, *dict;
262+ PyObject *tmp_obj;
263+ int i;
264+
265+ module = Py_InitModule("_sqlite3", module_methods);
266+
267+ if (!module ||
268+ (row_setup_types() < 0) ||
269+ (cursor_setup_types() < 0) ||
270+ (connection_setup_types() < 0) ||
271+ (cache_setup_types() < 0) ||
272+ (statement_setup_types() < 0) ||
273+ (prepare_protocol_setup_types() < 0)
274+ ) {
275+ return;
276+ }
277+
278+ Py_INCREF(&ConnectionType);
279+ PyModule_AddObject(module, "Connection", (PyObject*) &ConnectionType);
280+ Py_INCREF(&CursorType);
281+ PyModule_AddObject(module, "Cursor", (PyObject*) &CursorType);
282+ Py_INCREF(&CacheType);
283+ PyModule_AddObject(module, "Statement", (PyObject*)&StatementType);
284+ Py_INCREF(&StatementType);
285+ PyModule_AddObject(module, "Cache", (PyObject*) &CacheType);
286+ Py_INCREF(&SQLitePrepareProtocolType);
287+ PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &SQLitePrepareProtocolType);
288+ Py_INCREF(&RowType);
289+ PyModule_AddObject(module, "Row", (PyObject*) &RowType);
290+
291+ if (!(dict = PyModule_GetDict(module))) {
292+ goto error;
293+ }
294+
295+ /*** Create DB-API Exception hierarchy */
296+
297+ if (!(Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
298+ goto error;
299+ }
300+ PyDict_SetItemString(dict, "Error", Error);
301+
302+ if (!(Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
303+ goto error;
304+ }
305+ PyDict_SetItemString(dict, "Warning", Warning);
306+
307+ /* Error subclasses */
308+
309+ if (!(InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", Error, NULL))) {
310+ goto error;
311+ }
312+ PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
313+
314+ if (!(DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", Error, NULL))) {
315+ goto error;
316+ }
317+ PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
318+
319+ /* DatabaseError subclasses */
320+
321+ if (!(InternalError = PyErr_NewException(MODULE_NAME ".InternalError", DatabaseError, NULL))) {
322+ goto error;
323+ }
324+ PyDict_SetItemString(dict, "InternalError", InternalError);
325+
326+ if (!(OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", DatabaseError, NULL))) {
327+ goto error;
328+ }
329+ PyDict_SetItemString(dict, "OperationalError", OperationalError);
330+
331+ if (!(ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", DatabaseError, NULL))) {
332+ goto error;
333+ }
334+ PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
335+
336+ if (!(IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", DatabaseError,NULL))) {
337+ goto error;
338+ }
339+ PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
340+
341+ if (!(DataError = PyErr_NewException(MODULE_NAME ".DataError", DatabaseError, NULL))) {
342+ goto error;
343+ }
344+ PyDict_SetItemString(dict, "DataError", DataError);
345+
346+ if (!(NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", DatabaseError, NULL))) {
347+ goto error;
348+ }
349+ PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
350+
351+ /* We just need "something" unique for OptimizedUnicode. It does not really
352+ * need to be a string subclass. Just anything that can act as a special
353+ * marker for us. So I pulled PyCell_Type out of my magic hat.
354+ */
355+ Py_INCREF((PyObject*)&PyCell_Type);
356+ OptimizedUnicode = (PyObject*)&PyCell_Type;
357+ PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
358+
359+ /* Set integer constants */
360+ for (i = 0; _int_constants[i].constant_name != 0; i++) {
361+ tmp_obj = PyInt_FromLong(_int_constants[i].constant_value);
362+ if (!tmp_obj) {
363+ goto error;
364+ }
365+ PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj);
366+ Py_DECREF(tmp_obj);
367+ }
368+
369+ if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
370+ goto error;
371+ }
372+ PyDict_SetItemString(dict, "version", tmp_obj);
373+ Py_DECREF(tmp_obj);
374+
375+ if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
376+ goto error;
377+ }
378+ PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
379+ Py_DECREF(tmp_obj);
380+
381+ /* initialize microprotocols layer */
382+ microprotocols_init(dict);
383+
384+ /* initialize the default converters */
385+ converters_init(dict);
386+
387+ _enable_callback_tracebacks = 0;
388+
389+ /* Original comment form _bsddb.c in the Python core. This is also still
390+ * needed nowadays for Python 2.3/2.4.
391+ *
392+ * PyEval_InitThreads is called here due to a quirk in python 1.5
393+ * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
394+ * The global interepreter lock is not initialized until the first
395+ * thread is created using thread.start_new_thread() or fork() is
396+ * called. that would cause the ALLOW_THREADS here to segfault due
397+ * to a null pointer reference if no threads or child processes
398+ * have been created. This works around that and is a no-op if
399+ * threads have already been initialized.
400+ * (see pybsddb-users mailing list post on 2002-08-07)
401+ */
402+ PyEval_InitThreads();
403+
404+error:
405+ if (PyErr_Occurred())
406+ {
407+ PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
408+ }
409+}
sys/src/cmd/python/Modules/_sqlite/module.h+57−0
@@ -0,0 +1,57 @@
1+/* module.h - definitions for the module
2+ *
3+ * Copyright (C) 2004-2006 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 PYSQLITE_VERSION "2.3.2"
29+
30+extern PyObject* Error;
31+extern PyObject* Warning;
32+extern PyObject* InterfaceError;
33+extern PyObject* DatabaseError;
34+extern PyObject* InternalError;
35+extern PyObject* OperationalError;
36+extern PyObject* ProgrammingError;
37+extern PyObject* IntegrityError;
38+extern PyObject* DataError;
39+extern PyObject* NotSupportedError;
40+
41+extern PyObject* 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+
55+#define PARSE_DECLTYPES 1
56+#define PARSE_COLNAMES 2
57+#endif
sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c+84−0
@@ -0,0 +1,84 @@
1+/* prepare_protocol.c - the protocol for preparing values for SQLite
2+ *
3+ * Copyright (C) 2005-2006 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 "prepare_protocol.h"
25+
26+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
27+{
28+ return 0;
29+}
30+
31+void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
32+{
33+ self->ob_type->tp_free((PyObject*)self);
34+}
35+
36+PyTypeObject SQLitePrepareProtocolType= {
37+ PyObject_HEAD_INIT(NULL)
38+ 0, /* ob_size */
39+ MODULE_NAME ".PrepareProtocol", /* tp_name */
40+ sizeof(SQLitePrepareProtocol), /* tp_basicsize */
41+ 0, /* tp_itemsize */
42+ (destructor)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)prepare_protocol_init, /* tp_init */
74+ 0, /* tp_alloc */
75+ 0, /* tp_new */
76+ 0 /* tp_free */
77+};
78+
79+extern int prepare_protocol_setup_types(void)
80+{
81+ SQLitePrepareProtocolType.tp_new = PyType_GenericNew;
82+ SQLitePrepareProtocolType.ob_type= &PyType_Type;
83+ return PyType_Ready(&SQLitePrepareProtocolType);
84+}
sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h+41−0
@@ -0,0 +1,41 @@
1+/* prepare_protocol.h - the protocol for preparing values for SQLite
2+ *
3+ * Copyright (C) 2005 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+} SQLitePrepareProtocol;
32+
33+extern PyTypeObject SQLitePrepareProtocolType;
34+
35+int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
36+void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
37+
38+int prepare_protocol_setup_types(void);
39+
40+#define UNKNOWN (-1)
41+#endif
sys/src/cmd/python/Modules/_sqlite/row.c+202−0
@@ -0,0 +1,202 @@
1+/* row.c - an enhanced tuple for database rows
2+ *
3+ * Copyright (C) 2005-2006 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 row_dealloc(Row* self)
29+{
30+ Py_XDECREF(self->data);
31+ Py_XDECREF(self->description);
32+
33+ self->ob_type->tp_free((PyObject*)self);
34+}
35+
36+int row_init(Row* self, PyObject* args, PyObject* kwargs)
37+{
38+ PyObject* data;
39+ 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*)&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* row_subscript(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 row_length(Row* self, PyObject* args, PyObject* kwargs)
137+{
138+ return PyTuple_GET_SIZE(self->data);
139+}
140+
141+static int row_print(Row* self, FILE *fp, int flags)
142+{
143+ return (&PyTuple_Type)->tp_print(self->data, fp, flags);
144+}
145+
146+
147+PyMappingMethods row_as_mapping = {
148+ /* mp_length */ (lenfunc)row_length,
149+ /* mp_subscript */ (binaryfunc)row_subscript,
150+ /* mp_ass_subscript */ (objobjargproc)0,
151+};
152+
153+
154+PyTypeObject RowType = {
155+ PyObject_HEAD_INIT(NULL)
156+ 0, /* ob_size */
157+ MODULE_NAME ".Row", /* tp_name */
158+ sizeof(Row), /* tp_basicsize */
159+ 0, /* tp_itemsize */
160+ (destructor)row_dealloc, /* tp_dealloc */
161+ (printfunc)row_print, /* tp_print */
162+ 0, /* tp_getattr */
163+ 0, /* tp_setattr */
164+ 0, /* tp_compare */
165+ 0, /* tp_repr */
166+ 0, /* tp_as_number */
167+ 0, /* tp_as_sequence */
168+ 0, /* tp_as_mapping */
169+ 0, /* tp_hash */
170+ 0, /* tp_call */
171+ 0, /* tp_str */
172+ 0, /* tp_getattro */
173+ 0, /* tp_setattro */
174+ 0, /* tp_as_buffer */
175+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
176+ 0, /* tp_doc */
177+ 0, /* tp_traverse */
178+ 0, /* tp_clear */
179+ 0, /* tp_richcompare */
180+ 0, /* tp_weaklistoffset */
181+ 0, /* tp_iter */
182+ 0, /* tp_iternext */
183+ 0, /* tp_methods */
184+ 0, /* tp_members */
185+ 0, /* tp_getset */
186+ 0, /* tp_base */
187+ 0, /* tp_dict */
188+ 0, /* tp_descr_get */
189+ 0, /* tp_descr_set */
190+ 0, /* tp_dictoffset */
191+ (initproc)row_init, /* tp_init */
192+ 0, /* tp_alloc */
193+ 0, /* tp_new */
194+ 0 /* tp_free */
195+};
196+
197+extern int row_setup_types(void)
198+{
199+ RowType.tp_new = PyType_GenericNew;
200+ RowType.tp_as_mapping = &row_as_mapping;
201+ return PyType_Ready(&RowType);
202+}
sys/src/cmd/python/Modules/_sqlite/row.h+39−0
@@ -0,0 +1,39 @@
1+/* row.h - an enhanced tuple for database rows
2+ *
3+ * Copyright (C) 2005 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+} Row;
34+
35+extern PyTypeObject RowType;
36+
37+int row_setup_types(void);
38+
39+#endif
sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h+34−0
@@ -0,0 +1,34 @@
1+/* sqlitecompat.h - compatibility macros
2+ *
3+ * Copyright (C) 2006 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_COMPAT_H
25+#define PYSQLITE_COMPAT_H
26+
27+/* define Py_ssize_t for pre-2.5 versions of Python */
28+
29+#if PY_VERSION_HEX < 0x02050000
30+typedef int Py_ssize_t;
31+typedef int (*lenfunc)(PyObject*);
32+#endif
33+
34+#endif
sys/src/cmd/python/Modules/_sqlite/statement.c+432−0
@@ -0,0 +1,432 @@
1+/* statement.c - the statement type
2+ *
3+ * Copyright (C) 2005-2006 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 "statement.h"
25+#include "cursor.h"
26+#include "connection.h"
27+#include "microprotocols.h"
28+#include "prepare_protocol.h"
29+#include "sqlitecompat.h"
30+
31+/* prototypes */
32+int check_remaining_sql(const char* tail);
33+
34+typedef enum {
35+ LINECOMMENT_1,
36+ IN_LINECOMMENT,
37+ COMMENTSTART_1,
38+ IN_COMMENT,
39+ COMMENTEND_1,
40+ NORMAL
41+} parse_remaining_sql_state;
42+
43+int statement_create(Statement* self, Connection* connection, PyObject* sql)
44+{
45+ const char* tail;
46+ int rc;
47+ PyObject* sql_str;
48+ char* sql_cstr;
49+
50+ self->st = NULL;
51+ self->in_use = 0;
52+
53+ if (PyString_Check(sql)) {
54+ sql_str = sql;
55+ Py_INCREF(sql_str);
56+ } else if (PyUnicode_Check(sql)) {
57+ sql_str = PyUnicode_AsUTF8String(sql);
58+ if (!sql_str) {
59+ rc = PYSQLITE_SQL_WRONG_TYPE;
60+ return rc;
61+ }
62+ } else {
63+ rc = PYSQLITE_SQL_WRONG_TYPE;
64+ return rc;
65+ }
66+
67+ self->in_weakreflist = NULL;
68+ self->sql = sql_str;
69+
70+ sql_cstr = PyString_AsString(sql_str);
71+
72+ rc = sqlite3_prepare(connection->db,
73+ sql_cstr,
74+ -1,
75+ &self->st,
76+ &tail);
77+
78+ self->db = connection->db;
79+
80+ if (rc == SQLITE_OK && check_remaining_sql(tail)) {
81+ (void)sqlite3_finalize(self->st);
82+ self->st = NULL;
83+ rc = PYSQLITE_TOO_MUCH_SQL;
84+ }
85+
86+ return rc;
87+}
88+
89+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter)
90+{
91+ int rc = SQLITE_OK;
92+ long longval;
93+#ifdef HAVE_LONG_LONG
94+ PY_LONG_LONG longlongval;
95+#endif
96+ const char* buffer;
97+ char* string;
98+ Py_ssize_t buflen;
99+ PyObject* stringval;
100+
101+ if (parameter == Py_None) {
102+ rc = sqlite3_bind_null(self->st, pos);
103+ } else if (PyInt_Check(parameter)) {
104+ longval = PyInt_AsLong(parameter);
105+ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
106+#ifdef HAVE_LONG_LONG
107+ } else if (PyLong_Check(parameter)) {
108+ longlongval = PyLong_AsLongLong(parameter);
109+ /* in the overflow error case, longlongval is -1, and an exception is set */
110+ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
111+#endif
112+ } else if (PyFloat_Check(parameter)) {
113+ rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
114+ } else if (PyBuffer_Check(parameter)) {
115+ if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
116+ rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
117+ } else {
118+ PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
119+ rc = -1;
120+ }
121+ } else if PyString_Check(parameter) {
122+ string = PyString_AsString(parameter);
123+ rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
124+ } else if PyUnicode_Check(parameter) {
125+ stringval = PyUnicode_AsUTF8String(parameter);
126+ string = PyString_AsString(stringval);
127+ rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
128+ Py_DECREF(stringval);
129+ } else {
130+ rc = -1;
131+ }
132+
133+ return rc;
134+}
135+
136+void statement_bind_parameters(Statement* self, PyObject* parameters)
137+{
138+ PyObject* current_param;
139+ PyObject* adapted;
140+ const char* binding_name;
141+ int i;
142+ int rc;
143+ int num_params_needed;
144+ int num_params;
145+
146+ Py_BEGIN_ALLOW_THREADS
147+ num_params_needed = sqlite3_bind_parameter_count(self->st);
148+ Py_END_ALLOW_THREADS
149+
150+ if (PyDict_Check(parameters)) {
151+ /* parameters passed as dictionary */
152+ for (i = 1; i <= num_params_needed; i++) {
153+ Py_BEGIN_ALLOW_THREADS
154+ binding_name = sqlite3_bind_parameter_name(self->st, i);
155+ Py_END_ALLOW_THREADS
156+ if (!binding_name) {
157+ PyErr_Format(ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
158+ return;
159+ }
160+
161+ binding_name++; /* skip first char (the colon) */
162+ current_param = PyDict_GetItemString(parameters, binding_name);
163+ if (!current_param) {
164+ PyErr_Format(ProgrammingError, "You did not supply a value for binding %d.", i);
165+ return;
166+ }
167+
168+ Py_INCREF(current_param);
169+ adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
170+ if (adapted) {
171+ Py_DECREF(current_param);
172+ } else {
173+ PyErr_Clear();
174+ adapted = current_param;
175+ }
176+
177+ rc = statement_bind_parameter(self, i, adapted);
178+ Py_DECREF(adapted);
179+
180+ if (rc != SQLITE_OK) {
181+ PyErr_Format(InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
182+ return;
183+ }
184+ }
185+ } else {
186+ /* parameters passed as sequence */
187+ num_params = PySequence_Length(parameters);
188+ if (num_params != num_params_needed) {
189+ PyErr_Format(ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
190+ num_params_needed, num_params);
191+ return;
192+ }
193+ for (i = 0; i < num_params; i++) {
194+ current_param = PySequence_GetItem(parameters, i);
195+ if (!current_param) {
196+ return;
197+ }
198+ adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
199+
200+ if (adapted) {
201+ Py_DECREF(current_param);
202+ } else {
203+ PyErr_Clear();
204+ adapted = current_param;
205+ }
206+
207+ rc = statement_bind_parameter(self, i + 1, adapted);
208+ Py_DECREF(adapted);
209+
210+ if (rc != SQLITE_OK) {
211+ PyErr_Format(InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
212+ return;
213+ }
214+ }
215+ }
216+}
217+
218+int statement_recompile(Statement* self, PyObject* params)
219+{
220+ const char* tail;
221+ int rc;
222+ char* sql_cstr;
223+ sqlite3_stmt* new_st;
224+
225+ sql_cstr = PyString_AsString(self->sql);
226+
227+ rc = sqlite3_prepare(self->db,
228+ sql_cstr,
229+ -1,
230+ &new_st,
231+ &tail);
232+
233+ if (rc == SQLITE_OK) {
234+ /* The efficient sqlite3_transfer_bindings is only available in SQLite
235+ * version 3.2.2 or later. For older SQLite releases, that might not
236+ * even define SQLITE_VERSION_NUMBER, we do it the manual way.
237+ */
238+ #ifdef SQLITE_VERSION_NUMBER
239+ #if SQLITE_VERSION_NUMBER >= 3002002
240+ (void)sqlite3_transfer_bindings(self->st, new_st);
241+ #endif
242+ #else
243+ statement_bind_parameters(self, params);
244+ #endif
245+
246+ (void)sqlite3_finalize(self->st);
247+ self->st = new_st;
248+ }
249+
250+ return rc;
251+}
252+
253+int statement_finalize(Statement* self)
254+{
255+ int rc;
256+
257+ rc = SQLITE_OK;
258+ if (self->st) {
259+ Py_BEGIN_ALLOW_THREADS
260+ rc = sqlite3_finalize(self->st);
261+ Py_END_ALLOW_THREADS
262+ self->st = NULL;
263+ }
264+
265+ self->in_use = 0;
266+
267+ return rc;
268+}
269+
270+int statement_reset(Statement* self)
271+{
272+ int rc;
273+
274+ rc = SQLITE_OK;
275+
276+ if (self->in_use && self->st) {
277+ Py_BEGIN_ALLOW_THREADS
278+ rc = sqlite3_reset(self->st);
279+ Py_END_ALLOW_THREADS
280+
281+ if (rc == SQLITE_OK) {
282+ self->in_use = 0;
283+ }
284+ }
285+
286+ return rc;
287+}
288+
289+void statement_mark_dirty(Statement* self)
290+{
291+ self->in_use = 1;
292+}
293+
294+void statement_dealloc(Statement* self)
295+{
296+ int rc;
297+
298+ if (self->st) {
299+ Py_BEGIN_ALLOW_THREADS
300+ rc = sqlite3_finalize(self->st);
301+ Py_END_ALLOW_THREADS
302+ }
303+
304+ self->st = NULL;
305+
306+ Py_XDECREF(self->sql);
307+
308+ if (self->in_weakreflist != NULL) {
309+ PyObject_ClearWeakRefs((PyObject*)self);
310+ }
311+
312+ self->ob_type->tp_free((PyObject*)self);
313+}
314+
315+/*
316+ * Checks if there is anything left in an SQL string after SQLite compiled it.
317+ * This is used to check if somebody tried to execute more than one SQL command
318+ * with one execute()/executemany() command, which the DB-API and we don't
319+ * allow.
320+ *
321+ * Returns 1 if there is more left than should be. 0 if ok.
322+ */
323+int check_remaining_sql(const char* tail)
324+{
325+ const char* pos = tail;
326+
327+ parse_remaining_sql_state state = NORMAL;
328+
329+ for (;;) {
330+ switch (*pos) {
331+ case 0:
332+ return 0;
333+ case '-':
334+ if (state == NORMAL) {
335+ state = LINECOMMENT_1;
336+ } else if (state == LINECOMMENT_1) {
337+ state = IN_LINECOMMENT;
338+ }
339+ break;
340+ case ' ':
341+ case '\t':
342+ break;
343+ case '\n':
344+ case 13:
345+ if (state == IN_LINECOMMENT) {
346+ state = NORMAL;
347+ }
348+ break;
349+ case '/':
350+ if (state == NORMAL) {
351+ state = COMMENTSTART_1;
352+ } else if (state == COMMENTEND_1) {
353+ state = NORMAL;
354+ } else if (state == COMMENTSTART_1) {
355+ return 1;
356+ }
357+ break;
358+ case '*':
359+ if (state == NORMAL) {
360+ return 1;
361+ } else if (state == LINECOMMENT_1) {
362+ return 1;
363+ } else if (state == COMMENTSTART_1) {
364+ state = IN_COMMENT;
365+ } else if (state == IN_COMMENT) {
366+ state = COMMENTEND_1;
367+ }
368+ break;
369+ default:
370+ if (state == COMMENTEND_1) {
371+ state = IN_COMMENT;
372+ } else if (state == IN_LINECOMMENT) {
373+ } else if (state == IN_COMMENT) {
374+ } else {
375+ return 1;
376+ }
377+ }
378+
379+ pos++;
380+ }
381+
382+ return 0;
383+}
384+
385+PyTypeObject StatementType = {
386+ PyObject_HEAD_INIT(NULL)
387+ 0, /* ob_size */
388+ MODULE_NAME ".Statement", /* tp_name */
389+ sizeof(Statement), /* tp_basicsize */
390+ 0, /* tp_itemsize */
391+ (destructor)statement_dealloc, /* tp_dealloc */
392+ 0, /* tp_print */
393+ 0, /* tp_getattr */
394+ 0, /* tp_setattr */
395+ 0, /* tp_compare */
396+ 0, /* tp_repr */
397+ 0, /* tp_as_number */
398+ 0, /* tp_as_sequence */
399+ 0, /* tp_as_mapping */
400+ 0, /* tp_hash */
401+ 0, /* tp_call */
402+ 0, /* tp_str */
403+ 0, /* tp_getattro */
404+ 0, /* tp_setattro */
405+ 0, /* tp_as_buffer */
406+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
407+ 0, /* tp_doc */
408+ 0, /* tp_traverse */
409+ 0, /* tp_clear */
410+ 0, /* tp_richcompare */
411+ offsetof(Statement, in_weakreflist), /* tp_weaklistoffset */
412+ 0, /* tp_iter */
413+ 0, /* tp_iternext */
414+ 0, /* tp_methods */
415+ 0, /* tp_members */
416+ 0, /* tp_getset */
417+ 0, /* tp_base */
418+ 0, /* tp_dict */
419+ 0, /* tp_descr_get */
420+ 0, /* tp_descr_set */
421+ 0, /* tp_dictoffset */
422+ (initproc)0, /* tp_init */
423+ 0, /* tp_alloc */
424+ 0, /* tp_new */
425+ 0 /* tp_free */
426+};
427+
428+extern int statement_setup_types(void)
429+{
430+ StatementType.tp_new = PyType_GenericNew;
431+ return PyType_Ready(&StatementType);
432+}
sys/src/cmd/python/Modules/_sqlite/statement.h+59−0
@@ -0,0 +1,59 @@
1+/* statement.h - definitions for the statement type
2+ *
3+ * Copyright (C) 2005 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+} Statement;
43+
44+extern PyTypeObject StatementType;
45+
46+int statement_create(Statement* self, Connection* connection, PyObject* sql);
47+void statement_dealloc(Statement* self);
48+
49+int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
50+void statement_bind_parameters(Statement* self, PyObject* parameters);
51+
52+int statement_recompile(Statement* self, PyObject* parameters);
53+int statement_finalize(Statement* self);
54+int statement_reset(Statement* self);
55+void statement_mark_dirty(Statement* self);
56+
57+int statement_setup_types(void);
58+
59+#endif
sys/src/cmd/python/Modules/_sqlite/util.c+96−0
@@ -0,0 +1,96 @@
1+/* util.c - various utility functions
2+ *
3+ * Copyright (C) 2005-2006 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 _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
28+)
29+{
30+ int rc;
31+
32+ Py_BEGIN_ALLOW_THREADS
33+ rc = sqlite3_step(statement);
34+ Py_END_ALLOW_THREADS
35+
36+ return rc;
37+}
38+
39+/**
40+ * Checks the SQLite error code and sets the appropriate DB-API exception.
41+ * Returns the error code (0 means no error occurred).
42+ */
43+int _seterror(sqlite3* db)
44+{
45+ int errorcode;
46+
47+ errorcode = sqlite3_errcode(db);
48+
49+ switch (errorcode)
50+ {
51+ case SQLITE_OK:
52+ PyErr_Clear();
53+ break;
54+ case SQLITE_INTERNAL:
55+ case SQLITE_NOTFOUND:
56+ PyErr_SetString(InternalError, sqlite3_errmsg(db));
57+ break;
58+ case SQLITE_NOMEM:
59+ (void)PyErr_NoMemory();
60+ break;
61+ case SQLITE_ERROR:
62+ case SQLITE_PERM:
63+ case SQLITE_ABORT:
64+ case SQLITE_BUSY:
65+ case SQLITE_LOCKED:
66+ case SQLITE_READONLY:
67+ case SQLITE_INTERRUPT:
68+ case SQLITE_IOERR:
69+ case SQLITE_FULL:
70+ case SQLITE_CANTOPEN:
71+ case SQLITE_PROTOCOL:
72+ case SQLITE_EMPTY:
73+ case SQLITE_SCHEMA:
74+ PyErr_SetString(OperationalError, sqlite3_errmsg(db));
75+ break;
76+ case SQLITE_CORRUPT:
77+ PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
78+ break;
79+ case SQLITE_TOOBIG:
80+ PyErr_SetString(DataError, sqlite3_errmsg(db));
81+ break;
82+ case SQLITE_CONSTRAINT:
83+ case SQLITE_MISMATCH:
84+ PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
85+ break;
86+ case SQLITE_MISUSE:
87+ PyErr_SetString(ProgrammingError, sqlite3_errmsg(db));
88+ break;
89+ default:
90+ PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
91+ break;
92+ }
93+
94+ return errorcode;
95+}
96+
sys/src/cmd/python/Modules/_sqlite/util.h+38−0
@@ -0,0 +1,38 @@
1+/* util.h - various utility functions
2+ *
3+ * Copyright (C) 2005-2006 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 _sqlite_step_with_busyhandler(sqlite3_stmt* statement, 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 _seterror(sqlite3* db);
38+#endif