mirror of
https://github.com/python/cpython.git
synced 2025-11-25 21:11:09 +00:00
Updated to pysqlite 2.4.1. Documentation additions will come later.
This commit is contained in:
parent
0e795e7d92
commit
1cc60ed214
17 changed files with 787 additions and 222 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* cursor.c - the cursor type
|
||||
*
|
||||
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
|
||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
||||
*
|
||||
* This file is part of pysqlite.
|
||||
*
|
||||
|
|
@ -80,7 +80,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
|
|||
|
||||
if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection))
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_INCREF(connection);
|
||||
|
|
@ -435,7 +435,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
if (multiple) {
|
||||
/* executemany() */
|
||||
if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
|
||||
|
|
@ -457,7 +457,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
} else {
|
||||
/* execute() */
|
||||
if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyString_Check(operation) && !PyUnicode_Check(operation)) {
|
||||
|
|
@ -506,53 +506,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
operation_cstr = PyString_AsString(operation_bytestr);
|
||||
}
|
||||
|
||||
/* reset description and rowcount */
|
||||
/* reset description */
|
||||
Py_DECREF(self->description);
|
||||
Py_INCREF(Py_None);
|
||||
self->description = Py_None;
|
||||
|
||||
Py_DECREF(self->rowcount);
|
||||
self->rowcount = PyInt_FromLong(-1L);
|
||||
if (!self->rowcount) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
statement_type = detect_statement_type(operation_cstr);
|
||||
if (self->connection->begin_statement) {
|
||||
switch (statement_type) {
|
||||
case STATEMENT_UPDATE:
|
||||
case STATEMENT_DELETE:
|
||||
case STATEMENT_INSERT:
|
||||
case STATEMENT_REPLACE:
|
||||
if (!self->connection->inTransaction) {
|
||||
result = _pysqlite_connection_begin(self->connection);
|
||||
if (!result) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
break;
|
||||
case STATEMENT_OTHER:
|
||||
/* it's a DDL statement or something similar
|
||||
- we better COMMIT first so it works for all cases */
|
||||
if (self->connection->inTransaction) {
|
||||
result = pysqlite_connection_commit(self->connection, NULL);
|
||||
if (!result) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
break;
|
||||
case STATEMENT_SELECT:
|
||||
if (multiple) {
|
||||
PyErr_SetString(pysqlite_ProgrammingError,
|
||||
"You cannot execute SELECT statements in executemany().");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func_args = PyTuple_New(1);
|
||||
if (!func_args) {
|
||||
goto error;
|
||||
|
|
@ -590,6 +548,42 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
pysqlite_statement_reset(self->statement);
|
||||
pysqlite_statement_mark_dirty(self->statement);
|
||||
|
||||
statement_type = detect_statement_type(operation_cstr);
|
||||
if (self->connection->begin_statement) {
|
||||
switch (statement_type) {
|
||||
case STATEMENT_UPDATE:
|
||||
case STATEMENT_DELETE:
|
||||
case STATEMENT_INSERT:
|
||||
case STATEMENT_REPLACE:
|
||||
if (!self->connection->inTransaction) {
|
||||
result = _pysqlite_connection_begin(self->connection);
|
||||
if (!result) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
break;
|
||||
case STATEMENT_OTHER:
|
||||
/* it's a DDL statement or something similar
|
||||
- we better COMMIT first so it works for all cases */
|
||||
if (self->connection->inTransaction) {
|
||||
result = pysqlite_connection_commit(self->connection, NULL);
|
||||
if (!result) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
break;
|
||||
case STATEMENT_SELECT:
|
||||
if (multiple) {
|
||||
PyErr_SetString(pysqlite_ProgrammingError,
|
||||
"You cannot execute SELECT statements in executemany().");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
parameters = PyIter_Next(parameters_iter);
|
||||
if (!parameters) {
|
||||
|
|
@ -603,11 +597,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (pysqlite_build_row_cast_map(self) != 0) {
|
||||
PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Keep trying the SQL statement until the schema stops changing. */
|
||||
while (1) {
|
||||
/* Actually execute the SQL statement. */
|
||||
|
|
@ -626,7 +615,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
continue;
|
||||
} else {
|
||||
/* If the database gave us an error, promote it to Python. */
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
(void)pysqlite_statement_reset(self->statement);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -638,17 +628,23 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
(void)pysqlite_statement_reset(self->statement);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
numcols = sqlite3_column_count(self->statement->st);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (pysqlite_build_row_cast_map(self) != 0) {
|
||||
PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) {
|
||||
if (self->description == Py_None) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
numcols = sqlite3_column_count(self->statement->st);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
Py_DECREF(self->description);
|
||||
self->description = PyTuple_New(numcols);
|
||||
if (!self->description) {
|
||||
|
|
@ -689,15 +685,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
case STATEMENT_DELETE:
|
||||
case STATEMENT_INSERT:
|
||||
case STATEMENT_REPLACE:
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
rowcount += (long)sqlite3_changes(self->connection->db);
|
||||
Py_END_ALLOW_THREADS
|
||||
Py_DECREF(self->rowcount);
|
||||
self->rowcount = PyInt_FromLong(rowcount);
|
||||
}
|
||||
|
||||
Py_DECREF(self->lastrowid);
|
||||
if (statement_type == STATEMENT_INSERT) {
|
||||
if (!multiple && statement_type == STATEMENT_INSERT) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
lastrowid = sqlite3_last_insert_rowid(self->connection->db);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
|
@ -714,14 +706,27 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
|||
}
|
||||
|
||||
error:
|
||||
/* just to be sure (implicit ROLLBACKs with ON CONFLICT ROLLBACK/OR
|
||||
* ROLLBACK could have happened */
|
||||
#ifdef SQLITE_VERSION_NUMBER
|
||||
#if SQLITE_VERSION_NUMBER >= 3002002
|
||||
self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Py_XDECREF(operation_bytestr);
|
||||
Py_XDECREF(parameters);
|
||||
Py_XDECREF(parameters_iter);
|
||||
Py_XDECREF(parameters_list);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(self->rowcount);
|
||||
self->rowcount = PyInt_FromLong(-1L);
|
||||
return NULL;
|
||||
} else {
|
||||
Py_DECREF(self->rowcount);
|
||||
self->rowcount = PyInt_FromLong(rowcount);
|
||||
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
|
@ -748,7 +753,7 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
|||
int statement_completed = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &script_obj)) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
|
||||
|
|
@ -788,7 +793,7 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
|||
&statement,
|
||||
&script_cstr);
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -796,17 +801,18 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
|||
rc = SQLITE_ROW;
|
||||
while (rc == SQLITE_ROW) {
|
||||
rc = _sqlite_step_with_busyhandler(statement, self->connection);
|
||||
/* TODO: we probably need more error handling here */
|
||||
}
|
||||
|
||||
if (rc != SQLITE_DONE) {
|
||||
(void)sqlite3_finalize(statement);
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(statement);
|
||||
if (rc != SQLITE_OK) {
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
|
@ -864,8 +870,9 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
|
|||
if (self->statement) {
|
||||
rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection);
|
||||
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
|
||||
(void)pysqlite_statement_reset(self->statement);
|
||||
Py_DECREF(next_row);
|
||||
_pysqlite_seterror(self->connection->db);
|
||||
_pysqlite_seterror(self->connection->db, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -890,15 +897,17 @@ PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args)
|
|||
return row;
|
||||
}
|
||||
|
||||
PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args)
|
||||
PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
|
||||
{
|
||||
static char *kwlist[] = {"size", NULL, NULL};
|
||||
|
||||
PyObject* row;
|
||||
PyObject* list;
|
||||
int maxrows = self->arraysize;
|
||||
int counter = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|i", &maxrows)) {
|
||||
return NULL;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list = PyList_New(0);
|
||||
|
|
@ -992,7 +1001,7 @@ static PyMethodDef cursor_methods[] = {
|
|||
PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
|
||||
{"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS,
|
||||
PyDoc_STR("Fetches one row from the resultset.")},
|
||||
{"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS,
|
||||
{"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS,
|
||||
PyDoc_STR("Fetches several rows from the resultset.")},
|
||||
{"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS,
|
||||
PyDoc_STR("Fetches all rows from the resultset.")},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue