1 | /* cursor.c - the cursor type
|
---|
2 | *
|
---|
3 | * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
---|
4 | *
|
---|
5 | * This file is part of pysqlite.
|
---|
6 | *
|
---|
7 | * This software is provided 'as-is', without any express or implied
|
---|
8 | * warranty. In no event will the authors be held liable for any damages
|
---|
9 | * arising from the use of this software.
|
---|
10 | *
|
---|
11 | * Permission is granted to anyone to use this software for any purpose,
|
---|
12 | * including commercial applications, and to alter it and redistribute it
|
---|
13 | * freely, subject to the following restrictions:
|
---|
14 | *
|
---|
15 | * 1. The origin of this software must not be misrepresented; you must not
|
---|
16 | * claim that you wrote the original software. If you use this software
|
---|
17 | * in a product, an acknowledgment in the product documentation would be
|
---|
18 | * appreciated but is not required.
|
---|
19 | * 2. Altered source versions must be plainly marked as such, and must not be
|
---|
20 | * misrepresented as being the original software.
|
---|
21 | * 3. This notice may not be removed or altered from any source distribution.
|
---|
22 | */
|
---|
23 |
|
---|
24 | #include "cursor.h"
|
---|
25 | #include "module.h"
|
---|
26 | #include "util.h"
|
---|
27 | #include "sqlitecompat.h"
|
---|
28 |
|
---|
29 | PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
|
---|
30 |
|
---|
31 | static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
|
---|
32 |
|
---|
33 | static pysqlite_StatementKind detect_statement_type(char* statement)
|
---|
34 | {
|
---|
35 | char buf[20];
|
---|
36 | char* src;
|
---|
37 | char* dst;
|
---|
38 |
|
---|
39 | src = statement;
|
---|
40 | /* skip over whitepace */
|
---|
41 | while (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') {
|
---|
42 | src++;
|
---|
43 | }
|
---|
44 |
|
---|
45 | if (*src == 0)
|
---|
46 | return STATEMENT_INVALID;
|
---|
47 |
|
---|
48 | dst = buf;
|
---|
49 | *dst = 0;
|
---|
50 | while (Py_ISALPHA(*src) && dst - buf < sizeof(buf) - 2) {
|
---|
51 | *dst++ = Py_TOLOWER(*src++);
|
---|
52 | }
|
---|
53 |
|
---|
54 | *dst = 0;
|
---|
55 |
|
---|
56 | if (!strcmp(buf, "select")) {
|
---|
57 | return STATEMENT_SELECT;
|
---|
58 | } else if (!strcmp(buf, "insert")) {
|
---|
59 | return STATEMENT_INSERT;
|
---|
60 | } else if (!strcmp(buf, "update")) {
|
---|
61 | return STATEMENT_UPDATE;
|
---|
62 | } else if (!strcmp(buf, "delete")) {
|
---|
63 | return STATEMENT_DELETE;
|
---|
64 | } else if (!strcmp(buf, "replace")) {
|
---|
65 | return STATEMENT_REPLACE;
|
---|
66 | } else {
|
---|
67 | return STATEMENT_OTHER;
|
---|
68 | }
|
---|
69 | }
|
---|
70 |
|
---|
71 | static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
|
---|
72 | {
|
---|
73 | pysqlite_Connection* connection;
|
---|
74 |
|
---|
75 | if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection))
|
---|
76 | {
|
---|
77 | return -1;
|
---|
78 | }
|
---|
79 |
|
---|
80 | Py_INCREF(connection);
|
---|
81 | self->connection = connection;
|
---|
82 | self->statement = NULL;
|
---|
83 | self->next_row = NULL;
|
---|
84 | self->in_weakreflist = NULL;
|
---|
85 |
|
---|
86 | self->row_cast_map = PyList_New(0);
|
---|
87 | if (!self->row_cast_map) {
|
---|
88 | return -1;
|
---|
89 | }
|
---|
90 |
|
---|
91 | Py_INCREF(Py_None);
|
---|
92 | self->description = Py_None;
|
---|
93 |
|
---|
94 | Py_INCREF(Py_None);
|
---|
95 | self->lastrowid= Py_None;
|
---|
96 |
|
---|
97 | self->arraysize = 1;
|
---|
98 | self->closed = 0;
|
---|
99 | self->reset = 0;
|
---|
100 |
|
---|
101 | self->rowcount = -1L;
|
---|
102 |
|
---|
103 | Py_INCREF(Py_None);
|
---|
104 | self->row_factory = Py_None;
|
---|
105 |
|
---|
106 | if (!pysqlite_check_thread(self->connection)) {
|
---|
107 | return -1;
|
---|
108 | }
|
---|
109 |
|
---|
110 | if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) {
|
---|
111 | return -1;
|
---|
112 | }
|
---|
113 |
|
---|
114 | self->initialized = 1;
|
---|
115 |
|
---|
116 | return 0;
|
---|
117 | }
|
---|
118 |
|
---|
119 | static void pysqlite_cursor_dealloc(pysqlite_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 = pysqlite_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->row_factory);
|
---|
134 | Py_XDECREF(self->next_row);
|
---|
135 |
|
---|
136 | if (self->in_weakreflist != NULL) {
|
---|
137 | PyObject_ClearWeakRefs((PyObject*)self);
|
---|
138 | }
|
---|
139 |
|
---|
140 | self->ob_type->tp_free((PyObject*)self);
|
---|
141 | }
|
---|
142 |
|
---|
143 | PyObject* _pysqlite_get_converter(PyObject* key)
|
---|
144 | {
|
---|
145 | PyObject* upcase_key;
|
---|
146 | PyObject* retval;
|
---|
147 |
|
---|
148 | upcase_key = PyObject_CallMethod(key, "upper", "");
|
---|
149 | if (!upcase_key) {
|
---|
150 | return NULL;
|
---|
151 | }
|
---|
152 |
|
---|
153 | retval = PyDict_GetItem(converters, upcase_key);
|
---|
154 | Py_DECREF(upcase_key);
|
---|
155 |
|
---|
156 | return retval;
|
---|
157 | }
|
---|
158 |
|
---|
159 | int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
|
---|
160 | {
|
---|
161 | int i;
|
---|
162 | const char* type_start = (const char*)-1;
|
---|
163 | const char* pos;
|
---|
164 |
|
---|
165 | const char* colname;
|
---|
166 | const char* decltype;
|
---|
167 | PyObject* py_decltype;
|
---|
168 | PyObject* converter;
|
---|
169 | PyObject* key;
|
---|
170 |
|
---|
171 | if (!self->connection->detect_types) {
|
---|
172 | return 0;
|
---|
173 | }
|
---|
174 |
|
---|
175 | Py_XDECREF(self->row_cast_map);
|
---|
176 | self->row_cast_map = PyList_New(0);
|
---|
177 |
|
---|
178 | for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
|
---|
179 | converter = NULL;
|
---|
180 |
|
---|
181 | if (self->connection->detect_types & PARSE_COLNAMES) {
|
---|
182 | colname = sqlite3_column_name(self->statement->st, i);
|
---|
183 | if (colname) {
|
---|
184 | for (pos = colname; *pos != 0; pos++) {
|
---|
185 | if (*pos == '[') {
|
---|
186 | type_start = pos + 1;
|
---|
187 | } else if (*pos == ']' && type_start != (const char*)-1) {
|
---|
188 | key = PyString_FromStringAndSize(type_start, pos - type_start);
|
---|
189 | if (!key) {
|
---|
190 | /* creating a string failed, but it is too complicated
|
---|
191 | * to propagate the error here, we just assume there is
|
---|
192 | * no converter and proceed */
|
---|
193 | break;
|
---|
194 | }
|
---|
195 |
|
---|
196 | converter = _pysqlite_get_converter(key);
|
---|
197 | Py_DECREF(key);
|
---|
198 | break;
|
---|
199 | }
|
---|
200 | }
|
---|
201 | }
|
---|
202 | }
|
---|
203 |
|
---|
204 | if (!converter && self->connection->detect_types & PARSE_DECLTYPES) {
|
---|
205 | decltype = sqlite3_column_decltype(self->statement->st, i);
|
---|
206 | if (decltype) {
|
---|
207 | for (pos = decltype;;pos++) {
|
---|
208 | /* Converter names are split at '(' and blanks.
|
---|
209 | * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
|
---|
210 | * 'NUMBER(10)' to be treated as 'NUMBER', for example.
|
---|
211 | * In other words, it will work as people expect it to work.*/
|
---|
212 | if (*pos == ' ' || *pos == '(' || *pos == 0) {
|
---|
213 | py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
|
---|
214 | if (!py_decltype) {
|
---|
215 | return -1;
|
---|
216 | }
|
---|
217 | break;
|
---|
218 | }
|
---|
219 | }
|
---|
220 |
|
---|
221 | converter = _pysqlite_get_converter(py_decltype);
|
---|
222 | Py_DECREF(py_decltype);
|
---|
223 | }
|
---|
224 | }
|
---|
225 |
|
---|
226 | if (!converter) {
|
---|
227 | converter = Py_None;
|
---|
228 | }
|
---|
229 |
|
---|
230 | if (PyList_Append(self->row_cast_map, converter) != 0) {
|
---|
231 | if (converter != Py_None) {
|
---|
232 | Py_DECREF(converter);
|
---|
233 | }
|
---|
234 | Py_XDECREF(self->row_cast_map);
|
---|
235 | self->row_cast_map = NULL;
|
---|
236 |
|
---|
237 | return -1;
|
---|
238 | }
|
---|
239 | }
|
---|
240 |
|
---|
241 | return 0;
|
---|
242 | }
|
---|
243 |
|
---|
244 | PyObject* _pysqlite_build_column_name(const char* colname)
|
---|
245 | {
|
---|
246 | const char* pos;
|
---|
247 |
|
---|
248 | if (!colname) {
|
---|
249 | Py_INCREF(Py_None);
|
---|
250 | return Py_None;
|
---|
251 | }
|
---|
252 |
|
---|
253 | for (pos = colname;; pos++) {
|
---|
254 | if (*pos == 0 || *pos == '[') {
|
---|
255 | if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) {
|
---|
256 | pos--;
|
---|
257 | }
|
---|
258 | return PyString_FromStringAndSize(colname, pos - colname);
|
---|
259 | }
|
---|
260 | }
|
---|
261 | }
|
---|
262 |
|
---|
263 | PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t size, int optimize)
|
---|
264 | {
|
---|
265 | const char* check;
|
---|
266 | Py_ssize_t pos;
|
---|
267 | int is_ascii = 0;
|
---|
268 |
|
---|
269 | if (optimize) {
|
---|
270 | is_ascii = 1;
|
---|
271 |
|
---|
272 | check = val_str;
|
---|
273 | for (pos = 0; pos < size; pos++) {
|
---|
274 | if (*check & 0x80) {
|
---|
275 | is_ascii = 0;
|
---|
276 | break;
|
---|
277 | }
|
---|
278 |
|
---|
279 | check++;
|
---|
280 | }
|
---|
281 | }
|
---|
282 |
|
---|
283 | if (is_ascii) {
|
---|
284 | return PyString_FromStringAndSize(val_str, size);
|
---|
285 | } else {
|
---|
286 | return PyUnicode_DecodeUTF8(val_str, size, NULL);
|
---|
287 | }
|
---|
288 | }
|
---|
289 |
|
---|
290 | /*
|
---|
291 | * Returns a row from the currently active SQLite statement
|
---|
292 | *
|
---|
293 | * Precondidition:
|
---|
294 | * - sqlite3_step() has been called before and it returned SQLITE_ROW.
|
---|
295 | */
|
---|
296 | PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
---|
297 | {
|
---|
298 | int i, numcols;
|
---|
299 | PyObject* row;
|
---|
300 | PyObject* item = NULL;
|
---|
301 | int coltype;
|
---|
302 | PyObject* converter;
|
---|
303 | PyObject* converted;
|
---|
304 | Py_ssize_t nbytes;
|
---|
305 | PyObject* buffer;
|
---|
306 | void* raw_buffer;
|
---|
307 | const char* val_str;
|
---|
308 | char buf[200];
|
---|
309 | const char* colname;
|
---|
310 |
|
---|
311 | if (self->reset) {
|
---|
312 | PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
---|
313 | return NULL;
|
---|
314 | }
|
---|
315 |
|
---|
316 | Py_BEGIN_ALLOW_THREADS
|
---|
317 | numcols = sqlite3_data_count(self->statement->st);
|
---|
318 | Py_END_ALLOW_THREADS
|
---|
319 |
|
---|
320 | row = PyTuple_New(numcols);
|
---|
321 | if (!row) {
|
---|
322 | return NULL;
|
---|
323 | }
|
---|
324 |
|
---|
325 | for (i = 0; i < numcols; i++) {
|
---|
326 | if (self->connection->detect_types) {
|
---|
327 | converter = PyList_GetItem(self->row_cast_map, i);
|
---|
328 | if (!converter) {
|
---|
329 | converter = Py_None;
|
---|
330 | }
|
---|
331 | } else {
|
---|
332 | converter = Py_None;
|
---|
333 | }
|
---|
334 |
|
---|
335 | if (converter != Py_None) {
|
---|
336 | nbytes = sqlite3_column_bytes(self->statement->st, i);
|
---|
337 | val_str = (const char*)sqlite3_column_blob(self->statement->st, i);
|
---|
338 | if (!val_str) {
|
---|
339 | Py_INCREF(Py_None);
|
---|
340 | converted = Py_None;
|
---|
341 | } else {
|
---|
342 | item = PyString_FromStringAndSize(val_str, nbytes);
|
---|
343 | if (!item) {
|
---|
344 | return NULL;
|
---|
345 | }
|
---|
346 | converted = PyObject_CallFunction(converter, "O", item);
|
---|
347 | Py_DECREF(item);
|
---|
348 | if (!converted) {
|
---|
349 | break;
|
---|
350 | }
|
---|
351 | }
|
---|
352 | } else {
|
---|
353 | Py_BEGIN_ALLOW_THREADS
|
---|
354 | coltype = sqlite3_column_type(self->statement->st, i);
|
---|
355 | Py_END_ALLOW_THREADS
|
---|
356 | if (coltype == SQLITE_NULL) {
|
---|
357 | Py_INCREF(Py_None);
|
---|
358 | converted = Py_None;
|
---|
359 | } else if (coltype == SQLITE_INTEGER) {
|
---|
360 | converted = _pysqlite_long_from_int64(sqlite3_column_int64(self->statement->st, i));
|
---|
361 | } else if (coltype == SQLITE_FLOAT) {
|
---|
362 | converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
|
---|
363 | } else if (coltype == SQLITE_TEXT) {
|
---|
364 | val_str = (const char*)sqlite3_column_text(self->statement->st, i);
|
---|
365 | nbytes = sqlite3_column_bytes(self->statement->st, i);
|
---|
366 | if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
|
---|
367 | || (self->connection->text_factory == pysqlite_OptimizedUnicode)) {
|
---|
368 |
|
---|
369 | converted = pysqlite_unicode_from_string(val_str, nbytes,
|
---|
370 | self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0);
|
---|
371 |
|
---|
372 | if (!converted) {
|
---|
373 | colname = sqlite3_column_name(self->statement->st, i);
|
---|
374 | if (!colname) {
|
---|
375 | colname = "<unknown column name>";
|
---|
376 | }
|
---|
377 | PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
|
---|
378 | colname , val_str);
|
---|
379 | PyErr_SetString(pysqlite_OperationalError, buf);
|
---|
380 | }
|
---|
381 | } else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
|
---|
382 | converted = PyString_FromStringAndSize(val_str, nbytes);
|
---|
383 | } else {
|
---|
384 | converted = PyObject_CallFunction(self->connection->text_factory, "s#", val_str, nbytes);
|
---|
385 | }
|
---|
386 | } else {
|
---|
387 | /* coltype == SQLITE_BLOB */
|
---|
388 | nbytes = sqlite3_column_bytes(self->statement->st, i);
|
---|
389 | buffer = PyBuffer_New(nbytes);
|
---|
390 | if (!buffer) {
|
---|
391 | break;
|
---|
392 | }
|
---|
393 | if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) {
|
---|
394 | break;
|
---|
395 | }
|
---|
396 | memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes);
|
---|
397 | converted = buffer;
|
---|
398 | }
|
---|
399 | }
|
---|
400 |
|
---|
401 | if (converted) {
|
---|
402 | PyTuple_SetItem(row, i, converted);
|
---|
403 | } else {
|
---|
404 | Py_INCREF(Py_None);
|
---|
405 | PyTuple_SetItem(row, i, Py_None);
|
---|
406 | }
|
---|
407 | }
|
---|
408 |
|
---|
409 | if (PyErr_Occurred()) {
|
---|
410 | Py_DECREF(row);
|
---|
411 | row = NULL;
|
---|
412 | }
|
---|
413 |
|
---|
414 | return row;
|
---|
415 | }
|
---|
416 |
|
---|
417 | /*
|
---|
418 | * Checks if a cursor object is usable.
|
---|
419 | *
|
---|
420 | * 0 => error; 1 => ok
|
---|
421 | */
|
---|
422 | static int check_cursor(pysqlite_Cursor* cur)
|
---|
423 | {
|
---|
424 | if (!cur->initialized) {
|
---|
425 | PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called.");
|
---|
426 | return 0;
|
---|
427 | }
|
---|
428 |
|
---|
429 | if (cur->closed) {
|
---|
430 | PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor.");
|
---|
431 | return 0;
|
---|
432 | }
|
---|
433 |
|
---|
434 | if (cur->locked) {
|
---|
435 | PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed.");
|
---|
436 | return 0;
|
---|
437 | }
|
---|
438 |
|
---|
439 | return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
|
---|
440 | }
|
---|
441 |
|
---|
442 | PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
---|
443 | {
|
---|
444 | PyObject* operation;
|
---|
445 | PyObject* operation_bytestr = NULL;
|
---|
446 | char* operation_cstr;
|
---|
447 | PyObject* parameters_list = NULL;
|
---|
448 | PyObject* parameters_iter = NULL;
|
---|
449 | PyObject* parameters = NULL;
|
---|
450 | int i;
|
---|
451 | int rc;
|
---|
452 | PyObject* func_args;
|
---|
453 | PyObject* result;
|
---|
454 | int numcols;
|
---|
455 | int statement_type;
|
---|
456 | PyObject* descriptor;
|
---|
457 | PyObject* second_argument = NULL;
|
---|
458 | int allow_8bit_chars;
|
---|
459 |
|
---|
460 | if (!check_cursor(self)) {
|
---|
461 | goto error;
|
---|
462 | }
|
---|
463 |
|
---|
464 | self->locked = 1;
|
---|
465 | self->reset = 0;
|
---|
466 |
|
---|
467 | /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
|
---|
468 | allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
|
---|
469 | (self->connection->text_factory != pysqlite_OptimizedUnicode));
|
---|
470 |
|
---|
471 | Py_XDECREF(self->next_row);
|
---|
472 | self->next_row = NULL;
|
---|
473 |
|
---|
474 | if (multiple) {
|
---|
475 | /* executemany() */
|
---|
476 | if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
|
---|
477 | goto error;
|
---|
478 | }
|
---|
479 |
|
---|
480 | if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
|
---|
481 | PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
|
---|
482 | goto error;
|
---|
483 | }
|
---|
484 |
|
---|
485 | if (PyIter_Check(second_argument)) {
|
---|
486 | /* iterator */
|
---|
487 | Py_INCREF(second_argument);
|
---|
488 | parameters_iter = second_argument;
|
---|
489 | } else {
|
---|
490 | /* sequence */
|
---|
491 | parameters_iter = PyObject_GetIter(second_argument);
|
---|
492 | if (!parameters_iter) {
|
---|
493 | goto error;
|
---|
494 | }
|
---|
495 | }
|
---|
496 | } else {
|
---|
497 | /* execute() */
|
---|
498 | if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
|
---|
499 | goto error;
|
---|
500 | }
|
---|
501 |
|
---|
502 | if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
|
---|
503 | PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode");
|
---|
504 | goto error;
|
---|
505 | }
|
---|
506 |
|
---|
507 | parameters_list = PyList_New(0);
|
---|
508 | if (!parameters_list) {
|
---|
509 | goto error;
|
---|
510 | }
|
---|
511 |
|
---|
512 | if (second_argument == NULL) {
|
---|
513 | second_argument = PyTuple_New(0);
|
---|
514 | if (!second_argument) {
|
---|
515 | goto error;
|
---|
516 | }
|
---|
517 | } else {
|
---|
518 | Py_INCREF(second_argument);
|
---|
519 | }
|
---|
520 | if (PyList_Append(parameters_list, second_argument) != 0) {
|
---|
521 | Py_DECREF(second_argument);
|
---|
522 | goto error;
|
---|
523 | }
|
---|
524 | Py_DECREF(second_argument);
|
---|
525 |
|
---|
526 | parameters_iter = PyObject_GetIter(parameters_list);
|
---|
527 | if (!parameters_iter) {
|
---|
528 | goto error;
|
---|
529 | }
|
---|
530 | }
|
---|
531 |
|
---|
532 | if (self->statement != NULL) {
|
---|
533 | /* There is an active statement */
|
---|
534 | rc = pysqlite_statement_reset(self->statement);
|
---|
535 | }
|
---|
536 |
|
---|
537 | if (PyString_Check(operation)) {
|
---|
538 | operation_cstr = PyString_AsString(operation);
|
---|
539 | } else {
|
---|
540 | operation_bytestr = PyUnicode_AsUTF8String(operation);
|
---|
541 | if (!operation_bytestr) {
|
---|
542 | goto error;
|
---|
543 | }
|
---|
544 |
|
---|
545 | operation_cstr = PyString_AsString(operation_bytestr);
|
---|
546 | }
|
---|
547 |
|
---|
548 | /* reset description and rowcount */
|
---|
549 | Py_DECREF(self->description);
|
---|
550 | Py_INCREF(Py_None);
|
---|
551 | self->description = Py_None;
|
---|
552 | self->rowcount = -1L;
|
---|
553 |
|
---|
554 | func_args = PyTuple_New(1);
|
---|
555 | if (!func_args) {
|
---|
556 | goto error;
|
---|
557 | }
|
---|
558 | Py_INCREF(operation);
|
---|
559 | if (PyTuple_SetItem(func_args, 0, operation) != 0) {
|
---|
560 | goto error;
|
---|
561 | }
|
---|
562 |
|
---|
563 | if (self->statement) {
|
---|
564 | (void)pysqlite_statement_reset(self->statement);
|
---|
565 | Py_DECREF(self->statement);
|
---|
566 | }
|
---|
567 |
|
---|
568 | self->statement = (pysqlite_Statement*)pysqlite_cache_get(self->connection->statement_cache, func_args);
|
---|
569 | Py_DECREF(func_args);
|
---|
570 |
|
---|
571 | if (!self->statement) {
|
---|
572 | goto error;
|
---|
573 | }
|
---|
574 |
|
---|
575 | if (self->statement->in_use) {
|
---|
576 | Py_DECREF(self->statement);
|
---|
577 | self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType);
|
---|
578 | if (!self->statement) {
|
---|
579 | goto error;
|
---|
580 | }
|
---|
581 | rc = pysqlite_statement_create(self->statement, self->connection, operation);
|
---|
582 | if (rc != SQLITE_OK) {
|
---|
583 | Py_CLEAR(self->statement);
|
---|
584 | goto error;
|
---|
585 | }
|
---|
586 | }
|
---|
587 |
|
---|
588 | pysqlite_statement_reset(self->statement);
|
---|
589 | pysqlite_statement_mark_dirty(self->statement);
|
---|
590 |
|
---|
591 | statement_type = detect_statement_type(operation_cstr);
|
---|
592 | if (self->connection->begin_statement) {
|
---|
593 | switch (statement_type) {
|
---|
594 | case STATEMENT_UPDATE:
|
---|
595 | case STATEMENT_DELETE:
|
---|
596 | case STATEMENT_INSERT:
|
---|
597 | case STATEMENT_REPLACE:
|
---|
598 | if (!self->connection->inTransaction) {
|
---|
599 | result = _pysqlite_connection_begin(self->connection);
|
---|
600 | if (!result) {
|
---|
601 | goto error;
|
---|
602 | }
|
---|
603 | Py_DECREF(result);
|
---|
604 | }
|
---|
605 | break;
|
---|
606 | case STATEMENT_OTHER:
|
---|
607 | /* it's a DDL statement or something similar
|
---|
608 | - we better COMMIT first so it works for all cases */
|
---|
609 | if (self->connection->inTransaction) {
|
---|
610 | result = pysqlite_connection_commit(self->connection, NULL);
|
---|
611 | if (!result) {
|
---|
612 | goto error;
|
---|
613 | }
|
---|
614 | Py_DECREF(result);
|
---|
615 | }
|
---|
616 | break;
|
---|
617 | case STATEMENT_SELECT:
|
---|
618 | if (multiple) {
|
---|
619 | PyErr_SetString(pysqlite_ProgrammingError,
|
---|
620 | "You cannot execute SELECT statements in executemany().");
|
---|
621 | goto error;
|
---|
622 | }
|
---|
623 | break;
|
---|
624 | }
|
---|
625 | }
|
---|
626 |
|
---|
627 | while (1) {
|
---|
628 | parameters = PyIter_Next(parameters_iter);
|
---|
629 | if (!parameters) {
|
---|
630 | break;
|
---|
631 | }
|
---|
632 |
|
---|
633 | pysqlite_statement_mark_dirty(self->statement);
|
---|
634 |
|
---|
635 | pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars);
|
---|
636 | if (PyErr_Occurred()) {
|
---|
637 | goto error;
|
---|
638 | }
|
---|
639 |
|
---|
640 | /* Keep trying the SQL statement until the schema stops changing. */
|
---|
641 | while (1) {
|
---|
642 | /* Actually execute the SQL statement. */
|
---|
643 | rc = pysqlite_step(self->statement->st, self->connection);
|
---|
644 | if (rc == SQLITE_DONE || rc == SQLITE_ROW) {
|
---|
645 | /* If it worked, let's get out of the loop */
|
---|
646 | break;
|
---|
647 | }
|
---|
648 | /* Something went wrong. Re-set the statement and try again. */
|
---|
649 | rc = pysqlite_statement_reset(self->statement);
|
---|
650 | if (rc == SQLITE_SCHEMA) {
|
---|
651 | /* If this was a result of the schema changing, let's try
|
---|
652 | again. */
|
---|
653 | rc = pysqlite_statement_recompile(self->statement, parameters);
|
---|
654 | if (rc == SQLITE_OK) {
|
---|
655 | continue;
|
---|
656 | } else {
|
---|
657 | /* If the database gave us an error, promote it to Python. */
|
---|
658 | (void)pysqlite_statement_reset(self->statement);
|
---|
659 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
660 | goto error;
|
---|
661 | }
|
---|
662 | } else {
|
---|
663 | if (PyErr_Occurred()) {
|
---|
664 | /* there was an error that occurred in a user-defined callback */
|
---|
665 | if (_enable_callback_tracebacks) {
|
---|
666 | PyErr_Print();
|
---|
667 | } else {
|
---|
668 | PyErr_Clear();
|
---|
669 | }
|
---|
670 | }
|
---|
671 | (void)pysqlite_statement_reset(self->statement);
|
---|
672 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
673 | goto error;
|
---|
674 | }
|
---|
675 | }
|
---|
676 |
|
---|
677 | if (pysqlite_build_row_cast_map(self) != 0) {
|
---|
678 | PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
|
---|
679 | goto error;
|
---|
680 | }
|
---|
681 |
|
---|
682 | if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
|
---|
683 | if (self->description == Py_None) {
|
---|
684 | Py_BEGIN_ALLOW_THREADS
|
---|
685 | numcols = sqlite3_column_count(self->statement->st);
|
---|
686 | Py_END_ALLOW_THREADS
|
---|
687 |
|
---|
688 | Py_DECREF(self->description);
|
---|
689 | self->description = PyTuple_New(numcols);
|
---|
690 | if (!self->description) {
|
---|
691 | goto error;
|
---|
692 | }
|
---|
693 | for (i = 0; i < numcols; i++) {
|
---|
694 | descriptor = PyTuple_New(7);
|
---|
695 | if (!descriptor) {
|
---|
696 | goto error;
|
---|
697 | }
|
---|
698 | PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i)));
|
---|
699 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
|
---|
700 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
|
---|
701 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);
|
---|
702 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None);
|
---|
703 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None);
|
---|
704 | Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None);
|
---|
705 | PyTuple_SetItem(self->description, i, descriptor);
|
---|
706 | }
|
---|
707 | }
|
---|
708 | }
|
---|
709 |
|
---|
710 | if (rc == SQLITE_ROW) {
|
---|
711 | if (multiple) {
|
---|
712 | PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements.");
|
---|
713 | goto error;
|
---|
714 | }
|
---|
715 |
|
---|
716 | self->next_row = _pysqlite_fetch_one_row(self);
|
---|
717 | } else if (rc == SQLITE_DONE && !multiple) {
|
---|
718 | pysqlite_statement_reset(self->statement);
|
---|
719 | Py_CLEAR(self->statement);
|
---|
720 | }
|
---|
721 |
|
---|
722 | switch (statement_type) {
|
---|
723 | case STATEMENT_UPDATE:
|
---|
724 | case STATEMENT_DELETE:
|
---|
725 | case STATEMENT_INSERT:
|
---|
726 | case STATEMENT_REPLACE:
|
---|
727 | if (self->rowcount == -1L) {
|
---|
728 | self->rowcount = 0L;
|
---|
729 | }
|
---|
730 | self->rowcount += (long)sqlite3_changes(self->connection->db);
|
---|
731 | }
|
---|
732 |
|
---|
733 | Py_DECREF(self->lastrowid);
|
---|
734 | if (!multiple && statement_type == STATEMENT_INSERT) {
|
---|
735 | sqlite_int64 lastrowid;
|
---|
736 | Py_BEGIN_ALLOW_THREADS
|
---|
737 | lastrowid = sqlite3_last_insert_rowid(self->connection->db);
|
---|
738 | Py_END_ALLOW_THREADS
|
---|
739 | self->lastrowid = _pysqlite_long_from_int64(lastrowid);
|
---|
740 | } else {
|
---|
741 | Py_INCREF(Py_None);
|
---|
742 | self->lastrowid = Py_None;
|
---|
743 | }
|
---|
744 |
|
---|
745 | if (multiple) {
|
---|
746 | rc = pysqlite_statement_reset(self->statement);
|
---|
747 | }
|
---|
748 | Py_XDECREF(parameters);
|
---|
749 | }
|
---|
750 |
|
---|
751 | error:
|
---|
752 | /* just to be sure (implicit ROLLBACKs with ON CONFLICT ROLLBACK/OR
|
---|
753 | * ROLLBACK could have happened */
|
---|
754 | #ifdef SQLITE_VERSION_NUMBER
|
---|
755 | #if SQLITE_VERSION_NUMBER >= 3002002
|
---|
756 | if (self->connection && self->connection->db)
|
---|
757 | self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db);
|
---|
758 | #endif
|
---|
759 | #endif
|
---|
760 |
|
---|
761 | Py_XDECREF(operation_bytestr);
|
---|
762 | Py_XDECREF(parameters);
|
---|
763 | Py_XDECREF(parameters_iter);
|
---|
764 | Py_XDECREF(parameters_list);
|
---|
765 |
|
---|
766 | self->locked = 0;
|
---|
767 |
|
---|
768 | if (PyErr_Occurred()) {
|
---|
769 | self->rowcount = -1L;
|
---|
770 | return NULL;
|
---|
771 | } else {
|
---|
772 | Py_INCREF(self);
|
---|
773 | return (PyObject*)self;
|
---|
774 | }
|
---|
775 | }
|
---|
776 |
|
---|
777 | PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args)
|
---|
778 | {
|
---|
779 | return _pysqlite_query_execute(self, 0, args);
|
---|
780 | }
|
---|
781 |
|
---|
782 | PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args)
|
---|
783 | {
|
---|
784 | return _pysqlite_query_execute(self, 1, args);
|
---|
785 | }
|
---|
786 |
|
---|
787 | PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
---|
788 | {
|
---|
789 | PyObject* script_obj;
|
---|
790 | PyObject* script_str = NULL;
|
---|
791 | const char* script_cstr;
|
---|
792 | sqlite3_stmt* statement;
|
---|
793 | int rc;
|
---|
794 | PyObject* result;
|
---|
795 |
|
---|
796 | if (!PyArg_ParseTuple(args, "O", &script_obj)) {
|
---|
797 | return NULL;
|
---|
798 | }
|
---|
799 |
|
---|
800 | if (!check_cursor(self)) {
|
---|
801 | return NULL;
|
---|
802 | }
|
---|
803 |
|
---|
804 | self->reset = 0;
|
---|
805 |
|
---|
806 | if (PyString_Check(script_obj)) {
|
---|
807 | script_cstr = PyString_AsString(script_obj);
|
---|
808 | } else if (PyUnicode_Check(script_obj)) {
|
---|
809 | script_str = PyUnicode_AsUTF8String(script_obj);
|
---|
810 | if (!script_str) {
|
---|
811 | return NULL;
|
---|
812 | }
|
---|
813 |
|
---|
814 | script_cstr = PyString_AsString(script_str);
|
---|
815 | } else {
|
---|
816 | PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string.");
|
---|
817 | return NULL;
|
---|
818 | }
|
---|
819 |
|
---|
820 | /* commit first */
|
---|
821 | result = pysqlite_connection_commit(self->connection, NULL);
|
---|
822 | if (!result) {
|
---|
823 | goto error;
|
---|
824 | }
|
---|
825 | Py_DECREF(result);
|
---|
826 |
|
---|
827 | while (1) {
|
---|
828 | Py_BEGIN_ALLOW_THREADS
|
---|
829 | rc = sqlite3_prepare(self->connection->db,
|
---|
830 | script_cstr,
|
---|
831 | -1,
|
---|
832 | &statement,
|
---|
833 | &script_cstr);
|
---|
834 | Py_END_ALLOW_THREADS
|
---|
835 | if (rc != SQLITE_OK) {
|
---|
836 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
837 | goto error;
|
---|
838 | }
|
---|
839 |
|
---|
840 | /* execute statement, and ignore results of SELECT statements */
|
---|
841 | rc = SQLITE_ROW;
|
---|
842 | while (rc == SQLITE_ROW) {
|
---|
843 | rc = pysqlite_step(statement, self->connection);
|
---|
844 | /* TODO: we probably need more error handling here */
|
---|
845 | }
|
---|
846 |
|
---|
847 | if (rc != SQLITE_DONE) {
|
---|
848 | (void)sqlite3_finalize(statement);
|
---|
849 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
850 | goto error;
|
---|
851 | }
|
---|
852 |
|
---|
853 | rc = sqlite3_finalize(statement);
|
---|
854 | if (rc != SQLITE_OK) {
|
---|
855 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
856 | goto error;
|
---|
857 | }
|
---|
858 |
|
---|
859 | if (*script_cstr == (char)0) {
|
---|
860 | break;
|
---|
861 | }
|
---|
862 | }
|
---|
863 |
|
---|
864 | error:
|
---|
865 | Py_XDECREF(script_str);
|
---|
866 |
|
---|
867 | if (PyErr_Occurred()) {
|
---|
868 | return NULL;
|
---|
869 | } else {
|
---|
870 | Py_INCREF(self);
|
---|
871 | return (PyObject*)self;
|
---|
872 | }
|
---|
873 | }
|
---|
874 |
|
---|
875 | PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self)
|
---|
876 | {
|
---|
877 | Py_INCREF(self);
|
---|
878 | return (PyObject*)self;
|
---|
879 | }
|
---|
880 |
|
---|
881 | PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
|
---|
882 | {
|
---|
883 | PyObject* next_row_tuple;
|
---|
884 | PyObject* next_row;
|
---|
885 | int rc;
|
---|
886 |
|
---|
887 | if (!check_cursor(self)) {
|
---|
888 | return NULL;
|
---|
889 | }
|
---|
890 |
|
---|
891 | if (self->reset) {
|
---|
892 | PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
---|
893 | return NULL;
|
---|
894 | }
|
---|
895 |
|
---|
896 | if (!self->next_row) {
|
---|
897 | if (self->statement) {
|
---|
898 | (void)pysqlite_statement_reset(self->statement);
|
---|
899 | Py_DECREF(self->statement);
|
---|
900 | self->statement = NULL;
|
---|
901 | }
|
---|
902 | return NULL;
|
---|
903 | }
|
---|
904 |
|
---|
905 | next_row_tuple = self->next_row;
|
---|
906 | self->next_row = NULL;
|
---|
907 |
|
---|
908 | if (self->row_factory != Py_None) {
|
---|
909 | next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple);
|
---|
910 | Py_DECREF(next_row_tuple);
|
---|
911 | } else {
|
---|
912 | next_row = next_row_tuple;
|
---|
913 | }
|
---|
914 |
|
---|
915 | if (self->statement) {
|
---|
916 | rc = pysqlite_step(self->statement->st, self->connection);
|
---|
917 | if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
|
---|
918 | (void)pysqlite_statement_reset(self->statement);
|
---|
919 | Py_DECREF(next_row);
|
---|
920 | _pysqlite_seterror(self->connection->db, NULL);
|
---|
921 | return NULL;
|
---|
922 | }
|
---|
923 |
|
---|
924 | if (rc == SQLITE_ROW) {
|
---|
925 | self->next_row = _pysqlite_fetch_one_row(self);
|
---|
926 | }
|
---|
927 | }
|
---|
928 |
|
---|
929 | return next_row;
|
---|
930 | }
|
---|
931 |
|
---|
932 | PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args)
|
---|
933 | {
|
---|
934 | PyObject* row;
|
---|
935 |
|
---|
936 | row = pysqlite_cursor_iternext(self);
|
---|
937 | if (!row && !PyErr_Occurred()) {
|
---|
938 | Py_INCREF(Py_None);
|
---|
939 | return Py_None;
|
---|
940 | }
|
---|
941 |
|
---|
942 | return row;
|
---|
943 | }
|
---|
944 |
|
---|
945 | PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
|
---|
946 | {
|
---|
947 | static char *kwlist[] = {"size", NULL, NULL};
|
---|
948 |
|
---|
949 | PyObject* row;
|
---|
950 | PyObject* list;
|
---|
951 | int maxrows = self->arraysize;
|
---|
952 | int counter = 0;
|
---|
953 |
|
---|
954 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) {
|
---|
955 | return NULL;
|
---|
956 | }
|
---|
957 |
|
---|
958 | list = PyList_New(0);
|
---|
959 | if (!list) {
|
---|
960 | return NULL;
|
---|
961 | }
|
---|
962 |
|
---|
963 | /* just make sure we enter the loop */
|
---|
964 | row = Py_None;
|
---|
965 |
|
---|
966 | while (row) {
|
---|
967 | row = pysqlite_cursor_iternext(self);
|
---|
968 | if (row) {
|
---|
969 | PyList_Append(list, row);
|
---|
970 | Py_DECREF(row);
|
---|
971 | } else {
|
---|
972 | break;
|
---|
973 | }
|
---|
974 |
|
---|
975 | if (++counter == maxrows) {
|
---|
976 | break;
|
---|
977 | }
|
---|
978 | }
|
---|
979 |
|
---|
980 | if (PyErr_Occurred()) {
|
---|
981 | Py_DECREF(list);
|
---|
982 | return NULL;
|
---|
983 | } else {
|
---|
984 | return list;
|
---|
985 | }
|
---|
986 | }
|
---|
987 |
|
---|
988 | PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args)
|
---|
989 | {
|
---|
990 | PyObject* row;
|
---|
991 | PyObject* list;
|
---|
992 |
|
---|
993 | list = PyList_New(0);
|
---|
994 | if (!list) {
|
---|
995 | return NULL;
|
---|
996 | }
|
---|
997 |
|
---|
998 | /* just make sure we enter the loop */
|
---|
999 | row = (PyObject*)Py_None;
|
---|
1000 |
|
---|
1001 | while (row) {
|
---|
1002 | row = pysqlite_cursor_iternext(self);
|
---|
1003 | if (row) {
|
---|
1004 | PyList_Append(list, row);
|
---|
1005 | Py_DECREF(row);
|
---|
1006 | }
|
---|
1007 | }
|
---|
1008 |
|
---|
1009 | if (PyErr_Occurred()) {
|
---|
1010 | Py_DECREF(list);
|
---|
1011 | return NULL;
|
---|
1012 | } else {
|
---|
1013 | return list;
|
---|
1014 | }
|
---|
1015 | }
|
---|
1016 |
|
---|
1017 | PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args)
|
---|
1018 | {
|
---|
1019 | /* don't care, return None */
|
---|
1020 | Py_INCREF(Py_None);
|
---|
1021 | return Py_None;
|
---|
1022 | }
|
---|
1023 |
|
---|
1024 | PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args)
|
---|
1025 | {
|
---|
1026 | if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
|
---|
1027 | return NULL;
|
---|
1028 | }
|
---|
1029 |
|
---|
1030 | if (self->statement) {
|
---|
1031 | (void)pysqlite_statement_reset(self->statement);
|
---|
1032 | Py_CLEAR(self->statement);
|
---|
1033 | }
|
---|
1034 |
|
---|
1035 | self->closed = 1;
|
---|
1036 |
|
---|
1037 | Py_INCREF(Py_None);
|
---|
1038 | return Py_None;
|
---|
1039 | }
|
---|
1040 |
|
---|
1041 | static PyMethodDef cursor_methods[] = {
|
---|
1042 | {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS,
|
---|
1043 | PyDoc_STR("Executes a SQL statement.")},
|
---|
1044 | {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS,
|
---|
1045 | PyDoc_STR("Repeatedly executes a SQL statement.")},
|
---|
1046 | {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS,
|
---|
1047 | PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
|
---|
1048 | {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS,
|
---|
1049 | PyDoc_STR("Fetches one row from the resultset.")},
|
---|
1050 | {"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS,
|
---|
1051 | PyDoc_STR("Fetches several rows from the resultset.")},
|
---|
1052 | {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS,
|
---|
1053 | PyDoc_STR("Fetches all rows from the resultset.")},
|
---|
1054 | {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS,
|
---|
1055 | PyDoc_STR("Closes the cursor.")},
|
---|
1056 | {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS,
|
---|
1057 | PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
|
---|
1058 | {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS,
|
---|
1059 | PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")},
|
---|
1060 | {NULL, NULL}
|
---|
1061 | };
|
---|
1062 |
|
---|
1063 | static struct PyMemberDef cursor_members[] =
|
---|
1064 | {
|
---|
1065 | {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), RO},
|
---|
1066 | {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO},
|
---|
1067 | {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
|
---|
1068 | {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO},
|
---|
1069 | {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO},
|
---|
1070 | {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
|
---|
1071 | {NULL}
|
---|
1072 | };
|
---|
1073 |
|
---|
1074 | static char cursor_doc[] =
|
---|
1075 | PyDoc_STR("SQLite database cursor class.");
|
---|
1076 |
|
---|
1077 | PyTypeObject pysqlite_CursorType = {
|
---|
1078 | PyVarObject_HEAD_INIT(NULL, 0)
|
---|
1079 | MODULE_NAME ".Cursor", /* tp_name */
|
---|
1080 | sizeof(pysqlite_Cursor), /* tp_basicsize */
|
---|
1081 | 0, /* tp_itemsize */
|
---|
1082 | (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */
|
---|
1083 | 0, /* tp_print */
|
---|
1084 | 0, /* tp_getattr */
|
---|
1085 | 0, /* tp_setattr */
|
---|
1086 | 0, /* tp_compare */
|
---|
1087 | 0, /* tp_repr */
|
---|
1088 | 0, /* tp_as_number */
|
---|
1089 | 0, /* tp_as_sequence */
|
---|
1090 | 0, /* tp_as_mapping */
|
---|
1091 | 0, /* tp_hash */
|
---|
1092 | 0, /* tp_call */
|
---|
1093 | 0, /* tp_str */
|
---|
1094 | 0, /* tp_getattro */
|
---|
1095 | 0, /* tp_setattro */
|
---|
1096 | 0, /* tp_as_buffer */
|
---|
1097 | Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
|
---|
1098 | cursor_doc, /* tp_doc */
|
---|
1099 | 0, /* tp_traverse */
|
---|
1100 | 0, /* tp_clear */
|
---|
1101 | 0, /* tp_richcompare */
|
---|
1102 | offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */
|
---|
1103 | (getiterfunc)pysqlite_cursor_getiter, /* tp_iter */
|
---|
1104 | (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */
|
---|
1105 | cursor_methods, /* tp_methods */
|
---|
1106 | cursor_members, /* tp_members */
|
---|
1107 | 0, /* tp_getset */
|
---|
1108 | 0, /* tp_base */
|
---|
1109 | 0, /* tp_dict */
|
---|
1110 | 0, /* tp_descr_get */
|
---|
1111 | 0, /* tp_descr_set */
|
---|
1112 | 0, /* tp_dictoffset */
|
---|
1113 | (initproc)pysqlite_cursor_init, /* tp_init */
|
---|
1114 | 0, /* tp_alloc */
|
---|
1115 | 0, /* tp_new */
|
---|
1116 | 0 /* tp_free */
|
---|
1117 | };
|
---|
1118 |
|
---|
1119 | extern int pysqlite_cursor_setup_types(void)
|
---|
1120 | {
|
---|
1121 | pysqlite_CursorType.tp_new = PyType_GenericNew;
|
---|
1122 | return PyType_Ready(&pysqlite_CursorType);
|
---|
1123 | }
|
---|