@@ -92,6 +92,30 @@ isolation_level_converter(PyObject *str_or_none, const char **result)
92
92
return 1 ;
93
93
}
94
94
95
+ static int
96
+ autocommit_converter (PyObject * val , enum autocommit_mode * result )
97
+ {
98
+ if (Py_IsTrue (val )) {
99
+ * result = AUTOCOMMIT_ENABLED ;
100
+ return 1 ;
101
+ }
102
+ if (Py_IsFalse (val )) {
103
+ * result = AUTOCOMMIT_DISABLED ;
104
+ return 1 ;
105
+ }
106
+ if (PyLong_Check (val ) &&
107
+ PyLong_AsLong (val ) == DEPRECATED_TRANSACTION_CONTROL )
108
+ {
109
+ * result = AUTOCOMMIT_COMPAT ;
110
+ return 1 ;
111
+ }
112
+
113
+ PyErr_SetString (PyExc_ValueError ,
114
+ "autocommit must be True, False, or "
115
+ "sqlite3.DEPRECATED_TRANSACTION_CONTROL" );
116
+ return 0 ;
117
+ }
118
+
95
119
#define clinic_state () (pysqlite_get_state_by_type(Py_TYPE(self)))
96
120
#include "clinic/connection.c.h"
97
121
#undef clinic_state
@@ -132,13 +156,37 @@ new_statement_cache(pysqlite_Connection *self, pysqlite_state *state,
132
156
return res ;
133
157
}
134
158
159
+ static inline int
160
+ connection_txn_stmt (pysqlite_Connection * self , const char * sql )
161
+ {
162
+ int rc ;
163
+ Py_BEGIN_ALLOW_THREADS
164
+ sqlite3_stmt * stmt ;
165
+ rc = sqlite3_prepare_v2 (self -> db , sql , -1 , & stmt , NULL );
166
+ if (rc == SQLITE_OK ) {
167
+ (void )sqlite3_step (stmt );
168
+ rc = sqlite3_finalize (stmt );
169
+ }
170
+ Py_END_ALLOW_THREADS
171
+
172
+ if (rc != SQLITE_OK ) {
173
+ (void )_pysqlite_seterror (self -> state , self -> db );
174
+ return -1 ;
175
+ }
176
+ return 0 ;
177
+ }
178
+
135
179
/*[python input]
136
180
class IsolationLevel_converter(CConverter):
137
181
type = "const char *"
138
182
converter = "isolation_level_converter"
139
183
184
+ class Autocommit_converter(CConverter):
185
+ type = "enum autocommit_mode"
186
+ converter = "autocommit_converter"
187
+
140
188
[python start generated code]*/
141
- /*[python end generated code: output=da39a3ee5e6b4b0d input=cbcfe85b253061c2 ]*/
189
+ /*[python end generated code: output=da39a3ee5e6b4b0d input=bc2aa6c7ba0c5f8f ]*/
142
190
143
191
/*[clinic input]
144
192
_sqlite3.Connection.__init__ as pysqlite_connection_init
@@ -151,15 +199,17 @@ _sqlite3.Connection.__init__ as pysqlite_connection_init
151
199
factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType
152
200
cached_statements as cache_size: int = 128
153
201
uri: bool = False
202
+ autocommit: Autocommit(c_default='-1') = sqlite3.DEPRECATED_TRANSACTION_CONTROL
154
203
[clinic start generated code]*/
155
204
156
205
static int
157
206
pysqlite_connection_init_impl (pysqlite_Connection * self , PyObject * database ,
158
207
double timeout , int detect_types ,
159
208
const char * isolation_level ,
160
209
int check_same_thread , PyObject * factory ,
161
- int cache_size , int uri )
162
- /*[clinic end generated code: output=839eb2fee4293bda input=b8ce63dc6f70a383]*/
210
+ int cache_size , int uri ,
211
+ enum autocommit_mode autocommit )
212
+ /*[clinic end generated code: output=cba057313ea7712f input=82b8f749d645f63d]*/
163
213
{
164
214
if (PySys_Audit ("sqlite3.connect" , "O" , database ) < 0 ) {
165
215
return -1 ;
@@ -226,6 +276,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
226
276
self -> state = state ;
227
277
self -> detect_types = detect_types ;
228
278
self -> isolation_level = isolation_level ;
279
+ self -> autocommit = autocommit ;
229
280
self -> check_same_thread = check_same_thread ;
230
281
self -> thread_ident = PyThread_get_thread_ident ();
231
282
self -> statement_cache = statement_cache ;
@@ -255,6 +306,10 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
255
306
}
256
307
257
308
self -> initialized = 1 ;
309
+
310
+ if (autocommit == AUTOCOMMIT_DISABLED ) {
311
+ (void )connection_txn_stmt (self , "BEGIN" );
312
+ }
258
313
return 0 ;
259
314
260
315
error :
@@ -324,6 +379,12 @@ static void
324
379
connection_close (pysqlite_Connection * self )
325
380
{
326
381
if (self -> db ) {
382
+ if (self -> autocommit == AUTOCOMMIT_DISABLED &&
383
+ !sqlite3_get_autocommit (self -> db ))
384
+ {
385
+ (void )connection_txn_stmt (self , "ROLLBACK" );
386
+ }
387
+
327
388
free_callback_contexts (self );
328
389
329
390
sqlite3 * db = self -> db ;
@@ -533,24 +594,21 @@ pysqlite_connection_commit_impl(pysqlite_Connection *self)
533
594
return NULL ;
534
595
}
535
596
536
- if (!sqlite3_get_autocommit (self -> db )) {
537
- int rc ;
538
-
539
- Py_BEGIN_ALLOW_THREADS
540
- sqlite3_stmt * statement ;
541
- rc = sqlite3_prepare_v2 (self -> db , "COMMIT" , 7 , & statement , NULL );
542
- if (rc == SQLITE_OK ) {
543
- (void )sqlite3_step (statement );
544
- rc = sqlite3_finalize (statement );
597
+ if (self -> autocommit == AUTOCOMMIT_COMPAT ) {
598
+ if (!sqlite3_get_autocommit (self -> db )) {
599
+ if (connection_txn_stmt (self , "COMMIT" ) < 0 ) {
600
+ return NULL ;
601
+ }
545
602
}
546
- Py_END_ALLOW_THREADS
547
-
548
- if (rc != SQLITE_OK ) {
549
- (void )_pysqlite_seterror (self -> state , self -> db );
603
+ }
604
+ else if (self -> autocommit == AUTOCOMMIT_DISABLED ) {
605
+ if (connection_txn_stmt (self , "COMMIT" ) < 0 ) {
606
+ return NULL ;
607
+ }
608
+ if (connection_txn_stmt (self , "BEGIN" ) < 0 ) {
550
609
return NULL ;
551
610
}
552
611
}
553
-
554
612
Py_RETURN_NONE ;
555
613
}
556
614
@@ -568,25 +626,21 @@ pysqlite_connection_rollback_impl(pysqlite_Connection *self)
568
626
return NULL ;
569
627
}
570
628
571
- if (!sqlite3_get_autocommit (self -> db )) {
572
- int rc ;
573
-
574
- Py_BEGIN_ALLOW_THREADS
575
- sqlite3_stmt * statement ;
576
- rc = sqlite3_prepare_v2 (self -> db , "ROLLBACK" , 9 , & statement , NULL );
577
- if (rc == SQLITE_OK ) {
578
- (void )sqlite3_step (statement );
579
- rc = sqlite3_finalize (statement );
629
+ if (self -> autocommit == AUTOCOMMIT_COMPAT ) {
630
+ if (!sqlite3_get_autocommit (self -> db )) {
631
+ if (connection_txn_stmt (self , "ROLLBACK" ) < 0 ) {
632
+ return NULL ;
633
+ }
580
634
}
581
- Py_END_ALLOW_THREADS
582
-
583
- if (rc != SQLITE_OK ) {
584
- (void )_pysqlite_seterror (self -> state , self -> db );
635
+ }
636
+ else if (self -> autocommit == AUTOCOMMIT_DISABLED ) {
637
+ if (connection_txn_stmt (self , "ROLLBACK" ) < 0 ) {
638
+ return NULL ;
639
+ }
640
+ if (connection_txn_stmt (self , "BEGIN" ) < 0 ) {
585
641
return NULL ;
586
642
}
587
-
588
643
}
589
-
590
644
Py_RETURN_NONE ;
591
645
}
592
646
@@ -2264,13 +2318,42 @@ getlimit_impl(pysqlite_Connection *self, int category)
2264
2318
}
2265
2319
2266
2320
2321
+ static PyObject *
2322
+ get_autocommit (pysqlite_Connection * self , void * Py_UNUSED (ctx ))
2323
+ {
2324
+ if (!pysqlite_check_thread (self ) || !pysqlite_check_connection (self )) {
2325
+ return NULL ;
2326
+ }
2327
+ if (self -> autocommit == AUTOCOMMIT_ENABLED ) {
2328
+ Py_RETURN_TRUE ;
2329
+ }
2330
+ if (self -> autocommit == AUTOCOMMIT_DISABLED ) {
2331
+ Py_RETURN_FALSE ;
2332
+ }
2333
+ return PyLong_FromLong (DEPRECATED_TRANSACTION_CONTROL );
2334
+ }
2335
+
2336
+ static int
2337
+ set_autocommit (pysqlite_Connection * self , PyObject * val , void * Py_UNUSED (ctx ))
2338
+ {
2339
+ if (!pysqlite_check_thread (self ) || !pysqlite_check_connection (self )) {
2340
+ return -1 ;
2341
+ }
2342
+ if (!autocommit_converter (val , & self -> autocommit )) {
2343
+ return -1 ;
2344
+ }
2345
+ return 0 ;
2346
+ }
2347
+
2348
+
2267
2349
static const char connection_doc [] =
2268
2350
PyDoc_STR ("SQLite database connection object." );
2269
2351
2270
2352
static PyGetSetDef connection_getset [] = {
2271
2353
{"isolation_level" , (getter )pysqlite_connection_get_isolation_level , (setter )pysqlite_connection_set_isolation_level },
2272
2354
{"total_changes" , (getter )pysqlite_connection_get_total_changes , (setter )0 },
2273
2355
{"in_transaction" , (getter )pysqlite_connection_get_in_transaction , (setter )0 },
2356
+ {"autocommit" , (getter )get_autocommit , (setter )set_autocommit },
2274
2357
{NULL }
2275
2358
};
2276
2359
0 commit comments