1 | /* cursor.c - the cursor type |
2 | * |
3 | * Copyright (C) 2004-2010 Gerhard Häring <[email protected]> |
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 "clinic/cursor.c.h" |
28 | |
29 | static inline int |
30 | check_cursor_locked(pysqlite_Cursor *cur) |
31 | { |
32 | if (cur->locked) { |
33 | PyErr_SetString(pysqlite_ProgrammingError, |
34 | "Recursive use of cursors not allowed." ); |
35 | return 0; |
36 | } |
37 | return 1; |
38 | } |
39 | |
40 | /*[clinic input] |
41 | module _sqlite3 |
42 | class _sqlite3.Cursor "pysqlite_Cursor *" "pysqlite_CursorType" |
43 | [clinic start generated code]*/ |
44 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b2072d8db95411d5]*/ |
45 | |
46 | static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from." ; |
47 | |
48 | /*[clinic input] |
49 | _sqlite3.Cursor.__init__ as pysqlite_cursor_init |
50 | |
51 | connection: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType') |
52 | / |
53 | |
54 | [clinic start generated code]*/ |
55 | |
56 | static int |
57 | pysqlite_cursor_init_impl(pysqlite_Cursor *self, |
58 | pysqlite_Connection *connection) |
59 | /*[clinic end generated code: output=ac59dce49a809ca8 input=a8a4f75ac90999b2]*/ |
60 | { |
61 | if (!check_cursor_locked(self)) { |
62 | return -1; |
63 | } |
64 | |
65 | Py_INCREF(connection); |
66 | Py_XSETREF(self->connection, connection); |
67 | Py_CLEAR(self->statement); |
68 | Py_CLEAR(self->next_row); |
69 | Py_CLEAR(self->row_cast_map); |
70 | |
71 | Py_INCREF(Py_None); |
72 | Py_XSETREF(self->description, Py_None); |
73 | |
74 | Py_INCREF(Py_None); |
75 | Py_XSETREF(self->lastrowid, Py_None); |
76 | |
77 | self->arraysize = 1; |
78 | self->closed = 0; |
79 | self->reset = 0; |
80 | |
81 | self->rowcount = -1L; |
82 | |
83 | Py_INCREF(Py_None); |
84 | Py_XSETREF(self->row_factory, Py_None); |
85 | |
86 | if (!pysqlite_check_thread(self->connection)) { |
87 | return -1; |
88 | } |
89 | |
90 | if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) { |
91 | return -1; |
92 | } |
93 | |
94 | self->initialized = 1; |
95 | |
96 | return 0; |
97 | } |
98 | |
99 | static int |
100 | cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg) |
101 | { |
102 | Py_VISIT(Py_TYPE(self)); |
103 | Py_VISIT(self->connection); |
104 | Py_VISIT(self->description); |
105 | Py_VISIT(self->row_cast_map); |
106 | Py_VISIT(self->lastrowid); |
107 | Py_VISIT(self->row_factory); |
108 | Py_VISIT(self->statement); |
109 | Py_VISIT(self->next_row); |
110 | return 0; |
111 | } |
112 | |
113 | static int |
114 | cursor_clear(pysqlite_Cursor *self) |
115 | { |
116 | Py_CLEAR(self->connection); |
117 | Py_CLEAR(self->description); |
118 | Py_CLEAR(self->row_cast_map); |
119 | Py_CLEAR(self->lastrowid); |
120 | Py_CLEAR(self->row_factory); |
121 | if (self->statement) { |
122 | /* Reset the statement if the user has not closed the cursor */ |
123 | pysqlite_statement_reset(self->statement); |
124 | Py_CLEAR(self->statement); |
125 | } |
126 | Py_CLEAR(self->next_row); |
127 | |
128 | return 0; |
129 | } |
130 | |
131 | static void |
132 | cursor_dealloc(pysqlite_Cursor *self) |
133 | { |
134 | PyTypeObject *tp = Py_TYPE(self); |
135 | PyObject_GC_UnTrack(self); |
136 | if (self->in_weakreflist != NULL) { |
137 | PyObject_ClearWeakRefs((PyObject*)self); |
138 | } |
139 | tp->tp_clear((PyObject *)self); |
140 | tp->tp_free(self); |
141 | Py_DECREF(tp); |
142 | } |
143 | |
144 | static PyObject * |
145 | _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) |
146 | { |
147 | PyObject *key; |
148 | PyObject *upcase_key; |
149 | PyObject *retval; |
150 | _Py_IDENTIFIER(upper); |
151 | |
152 | key = PyUnicode_FromStringAndSize(keystr, keylen); |
153 | if (!key) { |
154 | return NULL; |
155 | } |
156 | upcase_key = _PyObject_CallMethodIdNoArgs(key, &PyId_upper); |
157 | Py_DECREF(key); |
158 | if (!upcase_key) { |
159 | return NULL; |
160 | } |
161 | |
162 | retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key); |
163 | Py_DECREF(upcase_key); |
164 | |
165 | return retval; |
166 | } |
167 | |
168 | static int |
169 | pysqlite_build_row_cast_map(pysqlite_Cursor* self) |
170 | { |
171 | int i; |
172 | const char* pos; |
173 | const char* decltype; |
174 | PyObject* converter; |
175 | |
176 | if (!self->connection->detect_types) { |
177 | return 0; |
178 | } |
179 | |
180 | Py_XSETREF(self->row_cast_map, PyList_New(0)); |
181 | if (!self->row_cast_map) { |
182 | return -1; |
183 | } |
184 | |
185 | for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { |
186 | converter = NULL; |
187 | |
188 | if (self->connection->detect_types & PARSE_COLNAMES) { |
189 | const char *colname = sqlite3_column_name(self->statement->st, i); |
190 | if (colname == NULL) { |
191 | PyErr_NoMemory(); |
192 | Py_CLEAR(self->row_cast_map); |
193 | return -1; |
194 | } |
195 | const char *type_start = NULL; |
196 | for (pos = colname; *pos != 0; pos++) { |
197 | if (*pos == '[') { |
198 | type_start = pos + 1; |
199 | } |
200 | else if (*pos == ']' && type_start != NULL) { |
201 | converter = _pysqlite_get_converter(type_start, pos - type_start); |
202 | if (!converter && PyErr_Occurred()) { |
203 | Py_CLEAR(self->row_cast_map); |
204 | return -1; |
205 | } |
206 | break; |
207 | } |
208 | } |
209 | } |
210 | |
211 | if (!converter && self->connection->detect_types & PARSE_DECLTYPES) { |
212 | decltype = sqlite3_column_decltype(self->statement->st, i); |
213 | if (decltype) { |
214 | for (pos = decltype;;pos++) { |
215 | /* Converter names are split at '(' and blanks. |
216 | * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and |
217 | * 'NUMBER(10)' to be treated as 'NUMBER', for example. |
218 | * In other words, it will work as people expect it to work.*/ |
219 | if (*pos == ' ' || *pos == '(' || *pos == 0) { |
220 | converter = _pysqlite_get_converter(decltype, pos - decltype); |
221 | if (!converter && PyErr_Occurred()) { |
222 | Py_CLEAR(self->row_cast_map); |
223 | return -1; |
224 | } |
225 | break; |
226 | } |
227 | } |
228 | } |
229 | } |
230 | |
231 | if (!converter) { |
232 | converter = Py_None; |
233 | } |
234 | |
235 | if (PyList_Append(self->row_cast_map, converter) != 0) { |
236 | Py_CLEAR(self->row_cast_map); |
237 | return -1; |
238 | } |
239 | } |
240 | |
241 | return 0; |
242 | } |
243 | |
244 | static PyObject * |
245 | _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname) |
246 | { |
247 | const char* pos; |
248 | Py_ssize_t len; |
249 | |
250 | if (self->connection->detect_types & PARSE_COLNAMES) { |
251 | for (pos = colname; *pos; pos++) { |
252 | if (*pos == '[') { |
253 | if ((pos != colname) && (*(pos-1) == ' ')) { |
254 | pos--; |
255 | } |
256 | break; |
257 | } |
258 | } |
259 | len = pos - colname; |
260 | } |
261 | else { |
262 | len = strlen(colname); |
263 | } |
264 | return PyUnicode_FromStringAndSize(colname, len); |
265 | } |
266 | |
267 | /* |
268 | * Returns a row from the currently active SQLite statement |
269 | * |
270 | * Precondidition: |
271 | * - sqlite3_step() has been called before and it returned SQLITE_ROW. |
272 | */ |
273 | static PyObject * |
274 | _pysqlite_fetch_one_row(pysqlite_Cursor* self) |
275 | { |
276 | int i, numcols; |
277 | PyObject* row; |
278 | int coltype; |
279 | PyObject* converter; |
280 | PyObject* converted; |
281 | Py_ssize_t nbytes; |
282 | char buf[200]; |
283 | const char* colname; |
284 | PyObject* error_msg; |
285 | |
286 | if (self->reset) { |
287 | PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); |
288 | return NULL; |
289 | } |
290 | |
291 | Py_BEGIN_ALLOW_THREADS |
292 | numcols = sqlite3_data_count(self->statement->st); |
293 | Py_END_ALLOW_THREADS |
294 | |
295 | row = PyTuple_New(numcols); |
296 | if (!row) |
297 | return NULL; |
298 | |
299 | sqlite3 *db = self->connection->db; |
300 | for (i = 0; i < numcols; i++) { |
301 | if (self->connection->detect_types |
302 | && self->row_cast_map != NULL |
303 | && i < PyList_GET_SIZE(self->row_cast_map)) |
304 | { |
305 | converter = PyList_GET_ITEM(self->row_cast_map, i); |
306 | } |
307 | else { |
308 | converter = Py_None; |
309 | } |
310 | |
311 | /* |
312 | * Note, sqlite3_column_bytes() must come after sqlite3_column_blob() |
313 | * or sqlite3_column_text(). |
314 | * |
315 | * See https://sqlite.org/c3ref/column_blob.html for details. |
316 | */ |
317 | if (converter != Py_None) { |
318 | const void *blob = sqlite3_column_blob(self->statement->st, i); |
319 | if (blob == NULL) { |
320 | if (sqlite3_errcode(db) == SQLITE_NOMEM) { |
321 | PyErr_NoMemory(); |
322 | goto error; |
323 | } |
324 | converted = Py_NewRef(Py_None); |
325 | } |
326 | else { |
327 | nbytes = sqlite3_column_bytes(self->statement->st, i); |
328 | PyObject *item = PyBytes_FromStringAndSize(blob, nbytes); |
329 | if (item == NULL) { |
330 | goto error; |
331 | } |
332 | converted = PyObject_CallOneArg(converter, item); |
333 | Py_DECREF(item); |
334 | } |
335 | } else { |
336 | Py_BEGIN_ALLOW_THREADS |
337 | coltype = sqlite3_column_type(self->statement->st, i); |
338 | Py_END_ALLOW_THREADS |
339 | if (coltype == SQLITE_NULL) { |
340 | converted = Py_NewRef(Py_None); |
341 | } else if (coltype == SQLITE_INTEGER) { |
342 | converted = PyLong_FromLongLong(sqlite3_column_int64(self->statement->st, i)); |
343 | } else if (coltype == SQLITE_FLOAT) { |
344 | converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); |
345 | } else if (coltype == SQLITE_TEXT) { |
346 | const char *text = (const char*)sqlite3_column_text(self->statement->st, i); |
347 | if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { |
348 | PyErr_NoMemory(); |
349 | goto error; |
350 | } |
351 | |
352 | nbytes = sqlite3_column_bytes(self->statement->st, i); |
353 | if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { |
354 | converted = PyUnicode_FromStringAndSize(text, nbytes); |
355 | if (!converted && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { |
356 | PyErr_Clear(); |
357 | colname = sqlite3_column_name(self->statement->st, i); |
358 | if (colname == NULL) { |
359 | PyErr_NoMemory(); |
360 | goto error; |
361 | } |
362 | PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'" , |
363 | colname , text); |
364 | error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii" , "replace" ); |
365 | if (!error_msg) { |
366 | PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8" ); |
367 | } else { |
368 | PyErr_SetObject(pysqlite_OperationalError, error_msg); |
369 | Py_DECREF(error_msg); |
370 | } |
371 | } |
372 | } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { |
373 | converted = PyBytes_FromStringAndSize(text, nbytes); |
374 | } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { |
375 | converted = PyByteArray_FromStringAndSize(text, nbytes); |
376 | } else { |
377 | converted = PyObject_CallFunction(self->connection->text_factory, "y#" , text, nbytes); |
378 | } |
379 | } else { |
380 | /* coltype == SQLITE_BLOB */ |
381 | const void *blob = sqlite3_column_blob(self->statement->st, i); |
382 | if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { |
383 | PyErr_NoMemory(); |
384 | goto error; |
385 | } |
386 | |
387 | nbytes = sqlite3_column_bytes(self->statement->st, i); |
388 | converted = PyBytes_FromStringAndSize(blob, nbytes); |
389 | } |
390 | } |
391 | |
392 | if (!converted) { |
393 | goto error; |
394 | } |
395 | PyTuple_SET_ITEM(row, i, converted); |
396 | } |
397 | |
398 | if (PyErr_Occurred()) |
399 | goto error; |
400 | |
401 | return row; |
402 | |
403 | error: |
404 | Py_DECREF(row); |
405 | return NULL; |
406 | } |
407 | |
408 | /* |
409 | * Checks if a cursor object is usable. |
410 | * |
411 | * 0 => error; 1 => ok |
412 | */ |
413 | static int check_cursor(pysqlite_Cursor* cur) |
414 | { |
415 | if (!cur->initialized) { |
416 | PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called." ); |
417 | return 0; |
418 | } |
419 | |
420 | if (cur->closed) { |
421 | PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor." ); |
422 | return 0; |
423 | } |
424 | |
425 | return (pysqlite_check_thread(cur->connection) |
426 | && pysqlite_check_connection(cur->connection) |
427 | && check_cursor_locked(cur)); |
428 | } |
429 | |
430 | static PyObject * |
431 | _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) |
432 | { |
433 | PyObject* parameters_list = NULL; |
434 | PyObject* parameters_iter = NULL; |
435 | PyObject* parameters = NULL; |
436 | int i; |
437 | int rc; |
438 | PyObject* func_args; |
439 | PyObject* result; |
440 | int numcols; |
441 | PyObject* column_name; |
442 | sqlite_int64 lastrowid; |
443 | |
444 | if (!check_cursor(self)) { |
445 | goto error; |
446 | } |
447 | |
448 | self->locked = 1; |
449 | self->reset = 0; |
450 | |
451 | Py_CLEAR(self->next_row); |
452 | |
453 | if (multiple) { |
454 | if (PyIter_Check(second_argument)) { |
455 | /* iterator */ |
456 | parameters_iter = Py_NewRef(second_argument); |
457 | } else { |
458 | /* sequence */ |
459 | parameters_iter = PyObject_GetIter(second_argument); |
460 | if (!parameters_iter) { |
461 | goto error; |
462 | } |
463 | } |
464 | } else { |
465 | parameters_list = PyList_New(0); |
466 | if (!parameters_list) { |
467 | goto error; |
468 | } |
469 | |
470 | if (second_argument == NULL) { |
471 | second_argument = PyTuple_New(0); |
472 | if (!second_argument) { |
473 | goto error; |
474 | } |
475 | } else { |
476 | Py_INCREF(second_argument); |
477 | } |
478 | if (PyList_Append(parameters_list, second_argument) != 0) { |
479 | Py_DECREF(second_argument); |
480 | goto error; |
481 | } |
482 | Py_DECREF(second_argument); |
483 | |
484 | parameters_iter = PyObject_GetIter(parameters_list); |
485 | if (!parameters_iter) { |
486 | goto error; |
487 | } |
488 | } |
489 | |
490 | if (self->statement != NULL) { |
491 | /* There is an active statement */ |
492 | pysqlite_statement_reset(self->statement); |
493 | } |
494 | |
495 | /* reset description and rowcount */ |
496 | Py_INCREF(Py_None); |
497 | Py_SETREF(self->description, Py_None); |
498 | self->rowcount = 0L; |
499 | |
500 | func_args = PyTuple_New(1); |
501 | if (!func_args) { |
502 | goto error; |
503 | } |
504 | if (PyTuple_SetItem(func_args, 0, Py_NewRef(operation)) != 0) { |
505 | goto error; |
506 | } |
507 | |
508 | if (self->statement) { |
509 | (void)pysqlite_statement_reset(self->statement); |
510 | } |
511 | |
512 | Py_XSETREF(self->statement, |
513 | (pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args)); |
514 | Py_DECREF(func_args); |
515 | |
516 | if (!self->statement) { |
517 | goto error; |
518 | } |
519 | |
520 | if (self->statement->in_use) { |
521 | Py_SETREF(self->statement, |
522 | pysqlite_statement_create(self->connection, operation)); |
523 | if (self->statement == NULL) { |
524 | goto error; |
525 | } |
526 | } |
527 | |
528 | pysqlite_statement_reset(self->statement); |
529 | pysqlite_statement_mark_dirty(self->statement); |
530 | |
531 | /* We start a transaction implicitly before a DML statement. |
532 | SELECT is the only exception. See #9924. */ |
533 | if (self->connection->begin_statement && self->statement->is_dml) { |
534 | if (sqlite3_get_autocommit(self->connection->db)) { |
535 | result = _pysqlite_connection_begin(self->connection); |
536 | if (!result) { |
537 | goto error; |
538 | } |
539 | Py_DECREF(result); |
540 | } |
541 | } |
542 | |
543 | while (1) { |
544 | parameters = PyIter_Next(parameters_iter); |
545 | if (!parameters) { |
546 | break; |
547 | } |
548 | |
549 | pysqlite_statement_mark_dirty(self->statement); |
550 | |
551 | pysqlite_statement_bind_parameters(self->statement, parameters); |
552 | if (PyErr_Occurred()) { |
553 | goto error; |
554 | } |
555 | |
556 | rc = pysqlite_step(self->statement->st, self->connection); |
557 | if (rc != SQLITE_DONE && rc != SQLITE_ROW) { |
558 | if (PyErr_Occurred()) { |
559 | /* there was an error that occurred in a user-defined callback */ |
560 | if (_pysqlite_enable_callback_tracebacks) { |
561 | PyErr_Print(); |
562 | } else { |
563 | PyErr_Clear(); |
564 | } |
565 | } |
566 | (void)pysqlite_statement_reset(self->statement); |
567 | _pysqlite_seterror(self->connection->db, NULL); |
568 | goto error; |
569 | } |
570 | |
571 | if (pysqlite_build_row_cast_map(self) != 0) { |
572 | _PyErr_FormatFromCause(pysqlite_OperationalError, "Error while building row_cast_map" ); |
573 | goto error; |
574 | } |
575 | |
576 | assert(rc == SQLITE_ROW || rc == SQLITE_DONE); |
577 | Py_BEGIN_ALLOW_THREADS |
578 | numcols = sqlite3_column_count(self->statement->st); |
579 | Py_END_ALLOW_THREADS |
580 | if (self->description == Py_None && numcols > 0) { |
581 | Py_SETREF(self->description, PyTuple_New(numcols)); |
582 | if (!self->description) { |
583 | goto error; |
584 | } |
585 | for (i = 0; i < numcols; i++) { |
586 | const char *colname; |
587 | colname = sqlite3_column_name(self->statement->st, i); |
588 | if (colname == NULL) { |
589 | PyErr_NoMemory(); |
590 | goto error; |
591 | } |
592 | column_name = _pysqlite_build_column_name(self, colname); |
593 | if (column_name == NULL) { |
594 | goto error; |
595 | } |
596 | PyObject *descriptor = PyTuple_Pack(7, column_name, |
597 | Py_None, Py_None, Py_None, |
598 | Py_None, Py_None, Py_None); |
599 | Py_DECREF(column_name); |
600 | if (descriptor == NULL) { |
601 | goto error; |
602 | } |
603 | PyTuple_SET_ITEM(self->description, i, descriptor); |
604 | } |
605 | } |
606 | |
607 | if (self->statement->is_dml) { |
608 | self->rowcount += (long)sqlite3_changes(self->connection->db); |
609 | } else { |
610 | self->rowcount= -1L; |
611 | } |
612 | |
613 | if (!multiple) { |
614 | Py_BEGIN_ALLOW_THREADS |
615 | lastrowid = sqlite3_last_insert_rowid(self->connection->db); |
616 | Py_END_ALLOW_THREADS |
617 | Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid)); |
618 | if (self->lastrowid == NULL) { |
619 | goto error; |
620 | } |
621 | } |
622 | |
623 | if (rc == SQLITE_ROW) { |
624 | if (multiple) { |
625 | PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements." ); |
626 | goto error; |
627 | } |
628 | |
629 | self->next_row = _pysqlite_fetch_one_row(self); |
630 | if (self->next_row == NULL) |
631 | goto error; |
632 | } else if (rc == SQLITE_DONE && !multiple) { |
633 | pysqlite_statement_reset(self->statement); |
634 | Py_CLEAR(self->statement); |
635 | } |
636 | |
637 | if (multiple) { |
638 | pysqlite_statement_reset(self->statement); |
639 | } |
640 | Py_XDECREF(parameters); |
641 | } |
642 | |
643 | error: |
644 | Py_XDECREF(parameters); |
645 | Py_XDECREF(parameters_iter); |
646 | Py_XDECREF(parameters_list); |
647 | |
648 | self->locked = 0; |
649 | |
650 | if (PyErr_Occurred()) { |
651 | self->rowcount = -1L; |
652 | return NULL; |
653 | } else { |
654 | return Py_NewRef((PyObject *)self); |
655 | } |
656 | } |
657 | |
658 | /*[clinic input] |
659 | _sqlite3.Cursor.execute as pysqlite_cursor_execute |
660 | |
661 | sql: unicode |
662 | parameters: object(c_default = 'NULL') = () |
663 | / |
664 | |
665 | Executes an SQL statement. |
666 | [clinic start generated code]*/ |
667 | |
668 | static PyObject * |
669 | pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, |
670 | PyObject *parameters) |
671 | /*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/ |
672 | { |
673 | return _pysqlite_query_execute(self, 0, sql, parameters); |
674 | } |
675 | |
676 | /*[clinic input] |
677 | _sqlite3.Cursor.executemany as pysqlite_cursor_executemany |
678 | |
679 | sql: unicode |
680 | seq_of_parameters: object |
681 | / |
682 | |
683 | Repeatedly executes an SQL statement. |
684 | [clinic start generated code]*/ |
685 | |
686 | static PyObject * |
687 | pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, |
688 | PyObject *seq_of_parameters) |
689 | /*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/ |
690 | { |
691 | return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); |
692 | } |
693 | |
694 | /*[clinic input] |
695 | _sqlite3.Cursor.executescript as pysqlite_cursor_executescript |
696 | |
697 | sql_script as script_obj: object |
698 | / |
699 | |
700 | Executes multiple SQL statements at once. |
701 | [clinic start generated code]*/ |
702 | |
703 | static PyObject * |
704 | pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) |
705 | /*[clinic end generated code: output=115a8132b0f200fe input=75270e5bcdb4d6aa]*/ |
706 | { |
707 | _Py_IDENTIFIER(commit); |
708 | const char* script_cstr; |
709 | sqlite3_stmt* statement; |
710 | int rc; |
711 | PyObject* result; |
712 | |
713 | if (!check_cursor(self)) { |
714 | return NULL; |
715 | } |
716 | |
717 | self->reset = 0; |
718 | |
719 | if (PyUnicode_Check(script_obj)) { |
720 | script_cstr = PyUnicode_AsUTF8(script_obj); |
721 | if (!script_cstr) { |
722 | return NULL; |
723 | } |
724 | } else { |
725 | PyErr_SetString(PyExc_ValueError, "script argument must be unicode." ); |
726 | return NULL; |
727 | } |
728 | |
729 | /* commit first */ |
730 | result = _PyObject_CallMethodIdNoArgs((PyObject *)self->connection, &PyId_commit); |
731 | if (!result) { |
732 | goto error; |
733 | } |
734 | Py_DECREF(result); |
735 | |
736 | while (1) { |
737 | Py_BEGIN_ALLOW_THREADS |
738 | rc = sqlite3_prepare_v2(self->connection->db, |
739 | script_cstr, |
740 | -1, |
741 | &statement, |
742 | &script_cstr); |
743 | Py_END_ALLOW_THREADS |
744 | if (rc != SQLITE_OK) { |
745 | _pysqlite_seterror(self->connection->db, NULL); |
746 | goto error; |
747 | } |
748 | |
749 | /* execute statement, and ignore results of SELECT statements */ |
750 | do { |
751 | rc = pysqlite_step(statement, self->connection); |
752 | if (PyErr_Occurred()) { |
753 | (void)sqlite3_finalize(statement); |
754 | goto error; |
755 | } |
756 | } while (rc == SQLITE_ROW); |
757 | |
758 | if (rc != SQLITE_DONE) { |
759 | (void)sqlite3_finalize(statement); |
760 | _pysqlite_seterror(self->connection->db, NULL); |
761 | goto error; |
762 | } |
763 | |
764 | rc = sqlite3_finalize(statement); |
765 | if (rc != SQLITE_OK) { |
766 | _pysqlite_seterror(self->connection->db, NULL); |
767 | goto error; |
768 | } |
769 | |
770 | if (*script_cstr == (char)0) { |
771 | break; |
772 | } |
773 | } |
774 | |
775 | error: |
776 | if (PyErr_Occurred()) { |
777 | return NULL; |
778 | } else { |
779 | return Py_NewRef((PyObject *)self); |
780 | } |
781 | } |
782 | |
783 | static PyObject * |
784 | pysqlite_cursor_iternext(pysqlite_Cursor *self) |
785 | { |
786 | PyObject* next_row_tuple; |
787 | PyObject* next_row; |
788 | int rc; |
789 | |
790 | if (!check_cursor(self)) { |
791 | return NULL; |
792 | } |
793 | |
794 | if (self->reset) { |
795 | PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); |
796 | return NULL; |
797 | } |
798 | |
799 | if (!self->next_row) { |
800 | if (self->statement) { |
801 | (void)pysqlite_statement_reset(self->statement); |
802 | Py_CLEAR(self->statement); |
803 | } |
804 | return NULL; |
805 | } |
806 | |
807 | next_row_tuple = self->next_row; |
808 | assert(next_row_tuple != NULL); |
809 | self->next_row = NULL; |
810 | |
811 | if (self->row_factory != Py_None) { |
812 | next_row = PyObject_CallFunction(self->row_factory, "OO" , self, next_row_tuple); |
813 | if (next_row == NULL) { |
814 | self->next_row = next_row_tuple; |
815 | return NULL; |
816 | } |
817 | Py_DECREF(next_row_tuple); |
818 | } else { |
819 | next_row = next_row_tuple; |
820 | } |
821 | |
822 | if (self->statement) { |
823 | rc = pysqlite_step(self->statement->st, self->connection); |
824 | if (PyErr_Occurred()) { |
825 | goto error; |
826 | } |
827 | if (rc != SQLITE_DONE && rc != SQLITE_ROW) { |
828 | _pysqlite_seterror(self->connection->db, NULL); |
829 | goto error; |
830 | } |
831 | |
832 | if (rc == SQLITE_ROW) { |
833 | self->locked = 1; // GH-80254: Prevent recursive use of cursors. |
834 | self->next_row = _pysqlite_fetch_one_row(self); |
835 | self->locked = 0; |
836 | if (self->next_row == NULL) { |
837 | goto error; |
838 | } |
839 | } |
840 | } |
841 | |
842 | return next_row; |
843 | |
844 | error: |
845 | (void)pysqlite_statement_reset(self->statement); |
846 | Py_DECREF(next_row); |
847 | return NULL; |
848 | } |
849 | |
850 | /*[clinic input] |
851 | _sqlite3.Cursor.fetchone as pysqlite_cursor_fetchone |
852 | |
853 | Fetches one row from the resultset. |
854 | [clinic start generated code]*/ |
855 | |
856 | static PyObject * |
857 | pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) |
858 | /*[clinic end generated code: output=4bd2eabf5baaddb0 input=e78294ec5980fdba]*/ |
859 | { |
860 | PyObject* row; |
861 | |
862 | row = pysqlite_cursor_iternext(self); |
863 | if (!row && !PyErr_Occurred()) { |
864 | Py_RETURN_NONE; |
865 | } |
866 | |
867 | return row; |
868 | } |
869 | |
870 | /*[clinic input] |
871 | _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany |
872 | |
873 | size as maxrows: int(c_default='self->arraysize') = 1 |
874 | The default value is set by the Cursor.arraysize attribute. |
875 | |
876 | Fetches several rows from the resultset. |
877 | [clinic start generated code]*/ |
878 | |
879 | static PyObject * |
880 | pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) |
881 | /*[clinic end generated code: output=a8ef31fea64d0906 input=c26e6ca3f34debd0]*/ |
882 | { |
883 | PyObject* row; |
884 | PyObject* list; |
885 | int counter = 0; |
886 | |
887 | list = PyList_New(0); |
888 | if (!list) { |
889 | return NULL; |
890 | } |
891 | |
892 | while ((row = pysqlite_cursor_iternext(self))) { |
893 | if (PyList_Append(list, row) < 0) { |
894 | Py_DECREF(row); |
895 | break; |
896 | } |
897 | Py_DECREF(row); |
898 | |
899 | if (++counter == maxrows) { |
900 | break; |
901 | } |
902 | } |
903 | |
904 | if (PyErr_Occurred()) { |
905 | Py_DECREF(list); |
906 | return NULL; |
907 | } else { |
908 | return list; |
909 | } |
910 | } |
911 | |
912 | /*[clinic input] |
913 | _sqlite3.Cursor.fetchall as pysqlite_cursor_fetchall |
914 | |
915 | Fetches all rows from the resultset. |
916 | [clinic start generated code]*/ |
917 | |
918 | static PyObject * |
919 | pysqlite_cursor_fetchall_impl(pysqlite_Cursor *self) |
920 | /*[clinic end generated code: output=d5da12aca2da4b27 input=f5d401086a8df25a]*/ |
921 | { |
922 | PyObject* row; |
923 | PyObject* list; |
924 | |
925 | list = PyList_New(0); |
926 | if (!list) { |
927 | return NULL; |
928 | } |
929 | |
930 | while ((row = pysqlite_cursor_iternext(self))) { |
931 | if (PyList_Append(list, row) < 0) { |
932 | Py_DECREF(row); |
933 | break; |
934 | } |
935 | Py_DECREF(row); |
936 | } |
937 | |
938 | if (PyErr_Occurred()) { |
939 | Py_DECREF(list); |
940 | return NULL; |
941 | } else { |
942 | return list; |
943 | } |
944 | } |
945 | |
946 | /*[clinic input] |
947 | _sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes |
948 | |
949 | sizes: object |
950 | / |
951 | |
952 | Required by DB-API. Does nothing in sqlite3. |
953 | [clinic start generated code]*/ |
954 | |
955 | static PyObject * |
956 | pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes) |
957 | /*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/ |
958 | { |
959 | Py_RETURN_NONE; |
960 | } |
961 | |
962 | /*[clinic input] |
963 | _sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize |
964 | |
965 | size: object |
966 | column: object = None |
967 | / |
968 | |
969 | Required by DB-API. Does nothing in sqlite3. |
970 | [clinic start generated code]*/ |
971 | |
972 | static PyObject * |
973 | pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, |
974 | PyObject *column) |
975 | /*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/ |
976 | { |
977 | Py_RETURN_NONE; |
978 | } |
979 | |
980 | /*[clinic input] |
981 | _sqlite3.Cursor.close as pysqlite_cursor_close |
982 | |
983 | Closes the cursor. |
984 | [clinic start generated code]*/ |
985 | |
986 | static PyObject * |
987 | pysqlite_cursor_close_impl(pysqlite_Cursor *self) |
988 | /*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ |
989 | { |
990 | if (!check_cursor_locked(self)) { |
991 | return NULL; |
992 | } |
993 | |
994 | if (!self->connection) { |
995 | PyErr_SetString(pysqlite_ProgrammingError, |
996 | "Base Cursor.__init__ not called." ); |
997 | return NULL; |
998 | } |
999 | if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { |
1000 | return NULL; |
1001 | } |
1002 | |
1003 | if (self->statement) { |
1004 | (void)pysqlite_statement_reset(self->statement); |
1005 | Py_CLEAR(self->statement); |
1006 | } |
1007 | |
1008 | self->closed = 1; |
1009 | |
1010 | Py_RETURN_NONE; |
1011 | } |
1012 | |
1013 | static PyMethodDef cursor_methods[] = { |
1014 | PYSQLITE_CURSOR_CLOSE_METHODDEF |
1015 | PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF |
1016 | PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF |
1017 | PYSQLITE_CURSOR_EXECUTE_METHODDEF |
1018 | PYSQLITE_CURSOR_FETCHALL_METHODDEF |
1019 | PYSQLITE_CURSOR_FETCHMANY_METHODDEF |
1020 | PYSQLITE_CURSOR_FETCHONE_METHODDEF |
1021 | PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF |
1022 | PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF |
1023 | {NULL, NULL} |
1024 | }; |
1025 | |
1026 | static struct PyMemberDef cursor_members[] = |
1027 | { |
1028 | {"connection" , T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY}, |
1029 | {"description" , T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY}, |
1030 | {"arraysize" , T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, |
1031 | {"lastrowid" , T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, |
1032 | {"rowcount" , T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, |
1033 | {"row_factory" , T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, |
1034 | {"__weaklistoffset__" , T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY}, |
1035 | {NULL} |
1036 | }; |
1037 | |
1038 | static const char cursor_doc[] = |
1039 | PyDoc_STR("SQLite database cursor class." ); |
1040 | |
1041 | static PyType_Slot cursor_slots[] = { |
1042 | {Py_tp_dealloc, cursor_dealloc}, |
1043 | {Py_tp_doc, (void *)cursor_doc}, |
1044 | {Py_tp_iter, PyObject_SelfIter}, |
1045 | {Py_tp_iternext, pysqlite_cursor_iternext}, |
1046 | {Py_tp_methods, cursor_methods}, |
1047 | {Py_tp_members, cursor_members}, |
1048 | {Py_tp_init, pysqlite_cursor_init}, |
1049 | {Py_tp_traverse, cursor_traverse}, |
1050 | {Py_tp_clear, cursor_clear}, |
1051 | {0, NULL}, |
1052 | }; |
1053 | |
1054 | static PyType_Spec cursor_spec = { |
1055 | .name = MODULE_NAME ".Cursor" , |
1056 | .basicsize = sizeof(pysqlite_Cursor), |
1057 | .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | |
1058 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), |
1059 | .slots = cursor_slots, |
1060 | }; |
1061 | |
1062 | PyTypeObject *pysqlite_CursorType = NULL; |
1063 | |
1064 | int |
1065 | pysqlite_cursor_setup_types(PyObject *module) |
1066 | { |
1067 | pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL); |
1068 | if (pysqlite_CursorType == NULL) { |
1069 | return -1; |
1070 | } |
1071 | return 0; |
1072 | } |
1073 | |