Issue #28037: Use sqlite3_get_autocommit() instead of setting Connection->inTransaction manually
Patch adapted from 9b79188edb
This commit is contained in:
parent
e7da2f8380
commit
59da4b324f
|
@ -143,6 +143,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #28037: Use sqlite3_get_autocommit() instead of setting
|
||||||
|
Connection->inTransaction manually.
|
||||||
|
|
||||||
- Issue #25283: Attributes tm_gmtoff and tm_zone are now available on
|
- Issue #25283: Attributes tm_gmtoff and tm_zone are now available on
|
||||||
all platforms in the return values of time.localtime() and
|
all platforms in the return values of time.localtime() and
|
||||||
time.gmtime().
|
time.gmtime().
|
||||||
|
|
|
@ -165,7 +165,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
|
||||||
self->statement_cache->decref_factory = 0;
|
self->statement_cache->decref_factory = 0;
|
||||||
Py_DECREF(self);
|
Py_DECREF(self);
|
||||||
|
|
||||||
self->inTransaction = 0;
|
|
||||||
self->detect_types = detect_types;
|
self->detect_types = detect_types;
|
||||||
self->timeout = timeout;
|
self->timeout = timeout;
|
||||||
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
|
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
|
||||||
|
@ -385,9 +384,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = pysqlite_step(statement, self);
|
rc = pysqlite_step(statement, self);
|
||||||
if (rc == SQLITE_DONE) {
|
if (rc != SQLITE_DONE) {
|
||||||
self->inTransaction = 1;
|
|
||||||
} else {
|
|
||||||
_pysqlite_seterror(self->db, statement);
|
_pysqlite_seterror(self->db, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +415,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->inTransaction) {
|
if (!sqlite3_get_autocommit(self->db)) {
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
|
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
|
||||||
|
@ -429,9 +426,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = pysqlite_step(statement, self);
|
rc = pysqlite_step(statement, self);
|
||||||
if (rc == SQLITE_DONE) {
|
if (rc != SQLITE_DONE) {
|
||||||
self->inTransaction = 0;
|
|
||||||
} else {
|
|
||||||
_pysqlite_seterror(self->db, statement);
|
_pysqlite_seterror(self->db, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +458,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->inTransaction) {
|
if (!sqlite3_get_autocommit(self->db)) {
|
||||||
pysqlite_do_all_statements(self, ACTION_RESET, 1);
|
pysqlite_do_all_statements(self, ACTION_RESET, 1);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
@ -475,9 +470,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = pysqlite_step(statement, self);
|
rc = pysqlite_step(statement, self);
|
||||||
if (rc == SQLITE_DONE) {
|
if (rc != SQLITE_DONE) {
|
||||||
self->inTransaction = 0;
|
|
||||||
} else {
|
|
||||||
_pysqlite_seterror(self->db, statement);
|
_pysqlite_seterror(self->db, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,6 +1151,17 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused)
|
||||||
|
{
|
||||||
|
if (!pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!sqlite3_get_autocommit(self->db)) {
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
}
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level)
|
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level)
|
||||||
{
|
{
|
||||||
if (isolation_level == Py_None) {
|
if (isolation_level == Py_None) {
|
||||||
|
@ -1168,7 +1172,6 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
|
||||||
self->begin_statement = NULL;
|
self->begin_statement = NULL;
|
||||||
self->inTransaction = 0;
|
|
||||||
} else {
|
} else {
|
||||||
const char * const *candidate;
|
const char * const *candidate;
|
||||||
PyObject *uppercase_level;
|
PyObject *uppercase_level;
|
||||||
|
@ -1606,6 +1609,7 @@ PyDoc_STR("SQLite database connection object.");
|
||||||
static PyGetSetDef connection_getset[] = {
|
static PyGetSetDef connection_getset[] = {
|
||||||
{"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
|
{"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
|
||||||
{"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0},
|
{"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0},
|
||||||
|
{"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1667,7 +1671,6 @@ static struct PyMemberDef connection_members[] =
|
||||||
{"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY},
|
{"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY},
|
||||||
{"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)},
|
{"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)},
|
||||||
{"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)},
|
{"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)},
|
||||||
{"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY},
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,6 @@ typedef struct
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
sqlite3* db;
|
sqlite3* db;
|
||||||
|
|
||||||
/* 1 if we are currently within a transaction, i. e. if a BEGIN has been
|
|
||||||
* issued */
|
|
||||||
char inTransaction;
|
|
||||||
|
|
||||||
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
|
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
|
||||||
* bitwise combination thereof makes sense */
|
* bitwise combination thereof makes sense */
|
||||||
int detect_types;
|
int detect_types;
|
||||||
|
|
|
@ -644,15 +644,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
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
|
|
||||||
if (self->connection && self->connection->db)
|
|
||||||
self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Py_XDECREF(parameters);
|
Py_XDECREF(parameters);
|
||||||
Py_XDECREF(parameters_iter);
|
Py_XDECREF(parameters_iter);
|
||||||
Py_XDECREF(parameters_list);
|
Py_XDECREF(parameters_list);
|
||||||
|
|
Loading…
Reference in New Issue