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 */
28Node* 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
49void 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
57int 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
89void 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
115PyObject* 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
214PyObject* 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
267static 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
275PyTypeObject 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
318PyTypeObject 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
361extern 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
32typedef 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
42typedef 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
61extern PyTypeObject NodeType;
62extern PyTypeObject CacheType;
63
64int node_init(Node* self, PyObject* args, PyObject* kwargs);
65void node_dealloc(Node* self);
66
67int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
68void cache_dealloc(Cache* self);
69PyObject* cache_get(Cache* self, PyObject* args);
70
71int 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
35static int connection_set_isolation_level(Connection* self, PyObject* isolation_level);
36
37
38void _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
50int 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 */
153void 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
172void 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
187void 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
211PyObject* 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
242PyObject* 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 */
274int 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
284PyObject* _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
314error:
315 if (PyErr_Occurred()) {
316 return NULL;
317 } else {
318 Py_INCREF(Py_None);
319 return Py_None;
320 }
321}
322
323PyObject* 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
358error:
359 if (PyErr_Occurred()) {
360 return NULL;
361 } else {
362 Py_INCREF(Py_None);
363 return Py_None;
364 }
365}
366
367PyObject* 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
404error:
405 if (PyErr_Occurred()) {
406 return NULL;
407 } else {
408 Py_INCREF(Py_None);
409 return Py_None;
410 }
411}
412
413void _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
448PyObject* _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
515void _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
548static 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
601error:
602 Py_XDECREF(stepmethod);
603 Py_XDECREF(function_result);
604
605 PyGILState_Release(threadstate);
606}
607
608void _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
640error:
641 Py_XDECREF(*aggregate_instance);
642 Py_XDECREF(function_result);
643
644 PyGILState_Release(threadstate);
645}
646
647void _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
679PyObject* 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
708PyObject* 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
735int _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
765PyObject* 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
790int 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
806static PyObject* connection_get_isolation_level(Connection* self, void* unused)
807{
808 Py_INCREF(self->isolation_level);
809 return self->isolation_level;
810}
811
812static 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
821static 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
869PyObject* 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
917error:
918 return (PyObject*)statement;
919}
920
921PyObject* 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
945error:
946 Py_XDECREF(result);
947 Py_XDECREF(method);
948
949 return cursor;
950}
951
952PyObject* 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
976error:
977 Py_XDECREF(result);
978 Py_XDECREF(method);
979
980 return cursor;
981}
982
983PyObject* 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
1007error:
1008 Py_XDECREF(result);
1009 Py_XDECREF(method);
1010
1011 return cursor;
1012}
1013
1014/* ------------------------- COLLATION CODE ------------------------ */
1015
1016static int
1017collation_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
1055finally:
1056 Py_XDECREF(string1);
1057 Py_XDECREF(string2);
1058 Py_XDECREF(retval);
1059
1060 PyGILState_Release(gilstate);
1061
1062 return result;
1063}
1064
1065static PyObject *
1066connection_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
1079finally:
1080 return retval;
1081}
1082
1083static PyObject *
1084connection_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
1141finally:
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
1154static char connection_doc[] =
1155PyDoc_STR("SQLite database connection object.");
1156
1157static 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
1163static 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
1191static 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
1208PyTypeObject 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
1251extern 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
35typedef 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
111extern PyTypeObject ConnectionType;
112
113PyObject* connection_alloc(PyTypeObject* type, int aware);
114void connection_dealloc(Connection* self);
115PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
116PyObject* connection_close(Connection* self, PyObject* args);
117PyObject* _connection_begin(Connection* self);
118PyObject* connection_begin(Connection* self, PyObject* args);
119PyObject* connection_commit(Connection* self, PyObject* args);
120PyObject* connection_rollback(Connection* self, PyObject* args);
121PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
122int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
123
124int check_thread(Connection* self);
125int check_connection(Connection* con);
126
127int 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
37PyObject* cursor_iternext(Cursor *self);
38
39static 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
77int 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
119void 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
140PyObject* _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
156int 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
237PyObject* _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
256PyObject* 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 */
288PyObject* _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
409PyObject* _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
706error:
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
720PyObject* cursor_execute(Cursor* self, PyObject* args)
721{
722 return _query_execute(self, 0, args);
723}
724
725PyObject* cursor_executemany(Cursor* self, PyObject* args)
726{
727 return _query_execute(self, 1, args);
728}
729
730PyObject* 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
804error:
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
819PyObject* cursor_getiter(Cursor *self)
820{
821 Py_INCREF(self);
822 return (PyObject*)self;
823}
824
825PyObject* 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
868PyObject* 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
881PyObject* 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
922PyObject* 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
951PyObject* pysqlite_noop(Connection* self, PyObject* args)
952{
953 /* don't care, return None */
954 Py_INCREF(Py_None);
955 return Py_None;
956}
957
958PyObject* 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
974static 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
996static 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
1007static char cursor_doc[] =
1008PyDoc_STR("SQLite database cursor class.");
1009
1010PyTypeObject 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
1053extern 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
32typedef 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
48typedef enum {
49 STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
50 STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
51 STATEMENT_OTHER
52} StatementKind;
53
54extern PyTypeObject CursorType;
55
56int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
57void cursor_dealloc(Cursor* self);
58PyObject* cursor_execute(Cursor* self, PyObject* args);
59PyObject* cursor_executemany(Cursor* self, PyObject* args);
60PyObject* cursor_getiter(Cursor *self);
61PyObject* cursor_iternext(Cursor *self);
62PyObject* cursor_fetchone(Cursor* self, PyObject* args);
63PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
64PyObject* cursor_fetchall(Cursor* self, PyObject* args);
65PyObject* pysqlite_noop(Connection* self, PyObject* args);
66PyObject* cursor_close(Cursor* self, PyObject* args);
67
68int 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
36PyObject *psyco_adapters;
37
38/* microprotocols_init - initialize the adapters dictionary */
39
40int
41microprotocols_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
54int
55microprotocols_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
75PyObject *
76microprotocols_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
134PyObject *
135psyco_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
32extern "C" {
33#endif
34
35/** adapters registry **/
36
37extern 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 */
48extern int microprotocols_init(PyObject *dict);
49extern int microprotocols_add(
50 PyTypeObject *type, PyObject *proto, PyObject *cast);
51extern PyObject *microprotocols_adapt(
52 PyObject *obj, PyObject *proto, PyObject *alt);
53
54extern 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
38PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
39 *OperationalError, *ProgrammingError, *IntegrityError, *DataError,
40 *NotSupportedError, *OptimizedUnicode;
41
42PyObject* converters;
43int _enable_callback_tracebacks;
44
45static 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
78static 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
103static 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
127static 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
142static 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;
170error:
171 if (name) {
172 PyMem_Free(name);
173 }
174 return retval;
175}
176
177static 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
187void converters_init(PyObject* dict)
188{
189 converters = PyDict_New();
190 if (!converters) {
191 return;
192 }
193
194 PyDict_SetItemString(dict, "converters", converters);
195}
196
197static 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
210struct _IntConstantPair {
211 char* constant_name;
212 int constant_value;
213};
214
215typedef struct _IntConstantPair IntConstantPair;
216
217static 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
259PyMODINIT_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
404error:
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
30extern PyObject* Error;
31extern PyObject* Warning;
32extern PyObject* InterfaceError;
33extern PyObject* DatabaseError;
34extern PyObject* InternalError;
35extern PyObject* OperationalError;
36extern PyObject* ProgrammingError;
37extern PyObject* IntegrityError;
38extern PyObject* DataError;
39extern PyObject* NotSupportedError;
40
41extern PyObject* OptimizedUnicode;
42
43/* the functions time.time() and time.sleep() */
44extern PyObject* time_time;
45extern 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 */
51extern PyObject* converters;
52
53extern 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
26int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
27{
28 return 0;
29}
30
31void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
32{
33 self->ob_type->tp_free((PyObject*)self);
34}
35
36PyTypeObject 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
79extern 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
28typedef struct
29{
30 PyObject_HEAD
31} SQLitePrepareProtocol;
32
33extern PyTypeObject SQLitePrepareProtocolType;
34
35int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
36void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
37
38int 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
28void 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
36int 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
67PyObject* 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
136Py_ssize_t row_length(Row* self, PyObject* args, PyObject* kwargs)
137{
138 return PyTuple_GET_SIZE(self->data);
139}
140
141static int row_print(Row* self, FILE *fp, int flags)
142{
143 return (&PyTuple_Type)->tp_print(self->data, fp, flags);
144}
145
146
147PyMappingMethods row_as_mapping = {
148 /* mp_length */ (lenfunc)row_length,
149 /* mp_subscript */ (binaryfunc)row_subscript,
150 /* mp_ass_subscript */ (objobjargproc)0,
151};
152
153
154PyTypeObject 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
197extern 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
28typedef struct _Row
29{
30 PyObject_HEAD
31 PyObject* data;
32 PyObject* description;
33} Row;
34
35extern PyTypeObject RowType;
36
37int 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
30typedef int Py_ssize_t;
31typedef 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 */
32int check_remaining_sql(const char* tail);
33
34typedef enum {
35 LINECOMMENT_1,
36 IN_LINECOMMENT,
37 COMMENTSTART_1,
38 IN_COMMENT,
39 COMMENTEND_1,
40 NORMAL
41} parse_remaining_sql_state;
42
43int 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
89int 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
136void 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
218int 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
253int 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
270int 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
289void statement_mark_dirty(Statement* self)
290{
291 self->in_use = 1;
292}
293
294void 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 */
323int 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
385PyTypeObject 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
428extern 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
34typedef 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
44extern PyTypeObject StatementType;
45
46int statement_create(Statement* self, Connection* connection, PyObject* sql);
47void statement_dealloc(Statement* self);
48
49int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
50void statement_bind_parameters(Statement* self, PyObject* parameters);
51
52int statement_recompile(Statement* self, PyObject* parameters);
53int statement_finalize(Statement* self);
54int statement_reset(Statement* self);
55void statement_mark_dirty(Statement* self);
56
57int 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
27int _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 */
43int _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
31int _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 */
37int _seterror(sqlite3* db);
38#endif