diff options
-rw-r--r-- | Lib/sqlite3/test/dbapi.py | 9 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.c | 24 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.h | 2 |
3 files changed, 20 insertions, 15 deletions
diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index b27486d..e774f74 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -297,6 +297,15 @@ class CursorTests(unittest.TestCase): self.cu.execute("update test set name='bar'") self.failUnlessEqual(self.cu.rowcount, 2) + def CheckRowcountSelect(self): + """ + pysqlite does not know the rowcount of SELECT statements, because we + don't fetch all rows after executing the select statement. The rowcount + has thus to be -1. + """ + self.cu.execute("select 5 union select 6") + self.failUnlessEqual(self.cu.rowcount, -1) + def CheckRowcountExecutemany(self): self.cu.execute("delete from test") self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)]) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 2321fa8..23d1e06 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -101,10 +101,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs self->arraysize = 1; - self->rowcount = PyInt_FromLong(-1L); - if (!self->rowcount) { - return -1; - } + self->rowcount = -1L; Py_INCREF(Py_None); self->row_factory = Py_None; @@ -130,7 +127,6 @@ void pysqlite_cursor_dealloc(pysqlite_Cursor* self) Py_XDECREF(self->row_cast_map); Py_XDECREF(self->description); Py_XDECREF(self->lastrowid); - Py_XDECREF(self->rowcount); Py_XDECREF(self->row_factory); Py_XDECREF(self->next_row); @@ -427,12 +423,12 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* int statement_type; PyObject* descriptor; PyObject* second_argument = NULL; - long rowcount = 0; int allow_8bit_chars; if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { return NULL; } + /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */ allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) && (self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode)); @@ -514,10 +510,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation_cstr = PyBytes_AsString(operation_bytestr); } - /* reset description */ + /* reset description and rowcount */ Py_DECREF(self->description); Py_INCREF(Py_None); self->description = Py_None; + self->rowcount = -1L; func_args = PyTuple_New(1); if (!func_args) { @@ -693,7 +690,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* case STATEMENT_DELETE: case STATEMENT_INSERT: case STATEMENT_REPLACE: - rowcount += (long)sqlite3_changes(self->connection->db); + if (self->rowcount == -1L) { + self->rowcount = 0L; + } + self->rowcount += (long)sqlite3_changes(self->connection->db); } Py_DECREF(self->lastrowid); @@ -728,13 +728,9 @@ error: Py_XDECREF(parameters_list); if (PyErr_Occurred()) { - Py_DECREF(self->rowcount); - self->rowcount = PyInt_FromLong(-1L); + self->rowcount = -1L; return NULL; } else { - Py_DECREF(self->rowcount); - self->rowcount = PyInt_FromLong(rowcount); - Py_INCREF(self); return (PyObject*)self; } @@ -1028,7 +1024,7 @@ static struct PyMemberDef cursor_members[] = {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO}, {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO}, - {"rowcount", T_OBJECT, offsetof(pysqlite_Cursor, rowcount), RO}, + {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO}, {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, {NULL} }; diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index d916ca5..54d816d 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -37,7 +37,7 @@ typedef struct PyObject* row_cast_map; int arraysize; PyObject* lastrowid; - PyObject* rowcount; + long rowcount; PyObject* row_factory; pysqlite_Statement* statement; |