Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 59da4b3

Browse files
committed
Issue #28037: Use sqlite3_get_autocommit() instead of setting Connection->inTransaction manually
Patch adapted from ghaering/pysqlite@9b79188
1 parent e7da2f8 commit 59da4b3

4 files changed

Lines changed: 20 additions & 27 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ Core and Builtins
143143
Library
144144
-------
145145

146+
- Issue #28037: Use sqlite3_get_autocommit() instead of setting
147+
Connection->inTransaction manually.
148+
146149
- Issue #25283: Attributes tm_gmtoff and tm_zone are now available on
147150
all platforms in the return values of time.localtime() and
148151
time.gmtime().

Modules/_sqlite/connection.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
165165
self->statement_cache->decref_factory = 0;
166166
Py_DECREF(self);
167167

168-
self->inTransaction = 0;
169168
self->detect_types = detect_types;
170169
self->timeout = timeout;
171170
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
@@ -385,9 +384,7 @@ PyObject* _pysqlite_connection_begin(pysqlite_Connection* self)
385384
}
386385

387386
rc = pysqlite_step(statement, self);
388-
if (rc == SQLITE_DONE) {
389-
self->inTransaction = 1;
390-
} else {
387+
if (rc != SQLITE_DONE) {
391388
_pysqlite_seterror(self->db, statement);
392389
}
393390

@@ -418,7 +415,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
418415
return NULL;
419416
}
420417

421-
if (self->inTransaction) {
418+
if (!sqlite3_get_autocommit(self->db)) {
422419

423420
Py_BEGIN_ALLOW_THREADS
424421
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
@@ -429,9 +426,7 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
429426
}
430427

431428
rc = pysqlite_step(statement, self);
432-
if (rc == SQLITE_DONE) {
433-
self->inTransaction = 0;
434-
} else {
429+
if (rc != SQLITE_DONE) {
435430
_pysqlite_seterror(self->db, statement);
436431
}
437432

@@ -463,7 +458,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
463458
return NULL;
464459
}
465460

466-
if (self->inTransaction) {
461+
if (!sqlite3_get_autocommit(self->db)) {
467462
pysqlite_do_all_statements(self, ACTION_RESET, 1);
468463

469464
Py_BEGIN_ALLOW_THREADS
@@ -475,9 +470,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
475470
}
476471

477472
rc = pysqlite_step(statement, self);
478-
if (rc == SQLITE_DONE) {
479-
self->inTransaction = 0;
480-
} else {
473+
if (rc != SQLITE_DONE) {
481474
_pysqlite_seterror(self->db, statement);
482475
}
483476

@@ -1158,6 +1151,17 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self
11581151
}
11591152
}
11601153

1154+
static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused)
1155+
{
1156+
if (!pysqlite_check_connection(self)) {
1157+
return NULL;
1158+
}
1159+
if (!sqlite3_get_autocommit(self->db)) {
1160+
Py_RETURN_TRUE;
1161+
}
1162+
Py_RETURN_FALSE;
1163+
}
1164+
11611165
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level)
11621166
{
11631167
if (isolation_level == Py_None) {
@@ -1168,7 +1172,6 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py
11681172
Py_DECREF(res);
11691173

11701174
self->begin_statement = NULL;
1171-
self->inTransaction = 0;
11721175
} else {
11731176
const char * const *candidate;
11741177
PyObject *uppercase_level;
@@ -1606,6 +1609,7 @@ PyDoc_STR("SQLite database connection object.");
16061609
static PyGetSetDef connection_getset[] = {
16071610
{"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
16081611
{"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0},
1612+
{"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0},
16091613
{NULL}
16101614
};
16111615

@@ -1667,7 +1671,6 @@ static struct PyMemberDef connection_members[] =
16671671
{"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY},
16681672
{"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)},
16691673
{"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)},
1670-
{"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY},
16711674
{NULL}
16721675
};
16731676

Modules/_sqlite/connection.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ typedef struct
3737
PyObject_HEAD
3838
sqlite3* db;
3939

40-
/* 1 if we are currently within a transaction, i. e. if a BEGIN has been
41-
* issued */
42-
char inTransaction;
43-
4440
/* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
4541
* bitwise combination thereof makes sense */
4642
int detect_types;

Modules/_sqlite/cursor.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -644,15 +644,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
644644
}
645645

646646
error:
647-
/* just to be sure (implicit ROLLBACKs with ON CONFLICT ROLLBACK/OR
648-
* ROLLBACK could have happened */
649-
#ifdef SQLITE_VERSION_NUMBER
650-
#if SQLITE_VERSION_NUMBER >= 3002002
651-
if (self->connection && self->connection->db)
652-
self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db);
653-
#endif
654-
#endif
655-
656647
Py_XDECREF(parameters);
657648
Py_XDECREF(parameters_iter);
658649
Py_XDECREF(parameters_list);

0 commit comments

Comments
 (0)