@@ -83,15 +83,17 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
83
83
static void free_callback_context (callback_context * ctx );
84
84
static void set_callback_context (callback_context * * ctx_pp ,
85
85
callback_context * ctx );
86
+ static void connection_close (pysqlite_Connection * self );
86
87
87
88
static PyObject *
88
- new_statement_cache (pysqlite_Connection * self , int maxsize )
89
+ new_statement_cache (pysqlite_Connection * self , pysqlite_state * state ,
90
+ int maxsize )
89
91
{
90
92
PyObject * args [] = { NULL , PyLong_FromLong (maxsize ), };
91
93
if (args [1 ] == NULL ) {
92
94
return NULL ;
93
95
}
94
- PyObject * lru_cache = self -> state -> lru_cache ;
96
+ PyObject * lru_cache = state -> lru_cache ;
95
97
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET ;
96
98
PyObject * inner = PyObject_Vectorcall (lru_cache , args + 1 , nargsf , NULL );
97
99
Py_DECREF (args [1 ]);
@@ -153,7 +155,7 @@ _sqlite3.Connection.__init__ as pysqlite_connection_init
153
155
isolation_level: str(accept={str, NoneType}) = ""
154
156
check_same_thread: bool(accept={int}) = True
155
157
factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType
156
- cached_statements: int = 128
158
+ cached_statements as cache_size : int = 128
157
159
uri: bool = False
158
160
[clinic start generated code]*/
159
161
@@ -162,78 +164,82 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
162
164
const char * database , double timeout ,
163
165
int detect_types , const char * isolation_level ,
164
166
int check_same_thread , PyObject * factory ,
165
- int cached_statements , int uri )
166
- /*[clinic end generated code: output=d8c37afc46d318b0 input=adfb29ac461f9e61 ]*/
167
+ int cache_size , int uri )
168
+ /*[clinic end generated code: output=7d640ae1d83abfd4 input=35e316f66d9f70fd ]*/
167
169
{
168
- int rc ;
169
-
170
170
if (PySys_Audit ("sqlite3.connect" , "s" , database ) < 0 ) {
171
171
return -1 ;
172
172
}
173
173
174
- pysqlite_state * state = pysqlite_get_state_by_type (Py_TYPE (self ));
175
- self -> state = state ;
176
-
177
- Py_CLEAR (self -> statement_cache );
178
- Py_CLEAR (self -> cursors );
179
-
180
- Py_INCREF (Py_None );
181
- Py_XSETREF (self -> row_factory , Py_None );
182
-
183
- Py_INCREF (& PyUnicode_Type );
184
- Py_XSETREF (self -> text_factory , (PyObject * )& PyUnicode_Type );
174
+ if (self -> initialized ) {
175
+ PyTypeObject * tp = Py_TYPE (self );
176
+ tp -> tp_clear ((PyObject * )self );
177
+ connection_close (self );
178
+ self -> initialized = 0 ;
179
+ }
185
180
181
+ // Create and configure SQLite database object.
182
+ sqlite3 * db ;
183
+ int rc ;
186
184
Py_BEGIN_ALLOW_THREADS
187
- rc = sqlite3_open_v2 (database , & self -> db ,
185
+ rc = sqlite3_open_v2 (database , & db ,
188
186
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
189
187
(uri ? SQLITE_OPEN_URI : 0 ), NULL );
188
+ if (rc == SQLITE_OK ) {
189
+ (void )sqlite3_busy_timeout (db , (int )(timeout * 1000 ));
190
+ }
190
191
Py_END_ALLOW_THREADS
191
192
192
- if (self -> db == NULL && rc == SQLITE_NOMEM ) {
193
+ if (db == NULL && rc == SQLITE_NOMEM ) {
193
194
PyErr_NoMemory ();
194
195
return -1 ;
195
196
}
197
+
198
+ pysqlite_state * state = pysqlite_get_state_by_type (Py_TYPE (self ));
196
199
if (rc != SQLITE_OK ) {
197
- _pysqlite_seterror (state , self -> db );
200
+ _pysqlite_seterror (state , db );
198
201
return -1 ;
199
202
}
200
203
201
- if (isolation_level ) {
202
- const char * stmt = get_begin_statement (isolation_level );
203
- if (stmt == NULL ) {
204
+ // Convert isolation level to begin statement.
205
+ const char * begin_statement = NULL ;
206
+ if (isolation_level != NULL ) {
207
+ begin_statement = get_begin_statement (isolation_level );
208
+ if (begin_statement == NULL ) {
204
209
return -1 ;
205
210
}
206
- self -> begin_statement = stmt ;
207
- }
208
- else {
209
- self -> begin_statement = NULL ;
210
211
}
211
212
212
- self -> statement_cache = new_statement_cache (self , cached_statements );
213
- if (self -> statement_cache == NULL ) {
214
- return -1 ;
215
- }
216
- if (PyErr_Occurred ()) {
213
+ // Create LRU statement cache; returns a new reference.
214
+ PyObject * statement_cache = new_statement_cache (self , state , cache_size );
215
+ if (statement_cache == NULL ) {
217
216
return -1 ;
218
217
}
219
218
220
- self -> created_cursors = 0 ;
221
-
222
- /* Create list of weak references to cursors */
223
- self -> cursors = PyList_New (0 );
224
- if (self -> cursors == NULL ) {
219
+ // Create list of weak references to cursors.
220
+ PyObject * cursors = PyList_New (0 );
221
+ if (cursors == NULL ) {
222
+ Py_DECREF (statement_cache );
225
223
return -1 ;
226
224
}
227
225
226
+ // Init connection state members.
227
+ self -> db = db ;
228
+ self -> state = state ;
228
229
self -> detect_types = detect_types ;
229
- (void )sqlite3_busy_timeout (self -> db , (int )(timeout * 1000 ));
230
- self -> thread_ident = PyThread_get_thread_ident ();
230
+ self -> begin_statement = begin_statement ;
231
231
self -> check_same_thread = check_same_thread ;
232
+ self -> thread_ident = PyThread_get_thread_ident ();
233
+ self -> statement_cache = statement_cache ;
234
+ self -> cursors = cursors ;
235
+ self -> created_cursors = 0 ;
236
+ self -> row_factory = Py_NewRef (Py_None );
237
+ self -> text_factory = Py_NewRef (& PyUnicode_Type );
238
+ self -> trace_ctx = NULL ;
239
+ self -> progress_ctx = NULL ;
240
+ self -> authorizer_ctx = NULL ;
232
241
233
- set_callback_context (& self -> trace_ctx , NULL );
234
- set_callback_context (& self -> progress_ctx , NULL );
235
- set_callback_context (& self -> authorizer_ctx , NULL );
236
-
242
+ // Borrowed refs
237
243
self -> Warning = state -> Warning ;
238
244
self -> Error = state -> Error ;
239
245
self -> InterfaceError = state -> InterfaceError ;
@@ -250,7 +256,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
250
256
}
251
257
252
258
self -> initialized = 1 ;
253
-
254
259
return 0 ;
255
260
}
256
261
@@ -321,16 +326,6 @@ connection_clear(pysqlite_Connection *self)
321
326
return 0 ;
322
327
}
323
328
324
- static void
325
- connection_close (pysqlite_Connection * self )
326
- {
327
- if (self -> db ) {
328
- int rc = sqlite3_close_v2 (self -> db );
329
- assert (rc == SQLITE_OK ), (void )rc ;
330
- self -> db = NULL ;
331
- }
332
- }
333
-
334
329
static void
335
330
free_callback_contexts (pysqlite_Connection * self )
336
331
{
@@ -339,6 +334,22 @@ free_callback_contexts(pysqlite_Connection *self)
339
334
set_callback_context (& self -> authorizer_ctx , NULL );
340
335
}
341
336
337
+ static void
338
+ connection_close (pysqlite_Connection * self )
339
+ {
340
+ if (self -> db ) {
341
+ free_callback_contexts (self );
342
+
343
+ sqlite3 * db = self -> db ;
344
+ self -> db = NULL ;
345
+
346
+ Py_BEGIN_ALLOW_THREADS
347
+ int rc = sqlite3_close_v2 (db );
348
+ assert (rc == SQLITE_OK ), (void )rc ;
349
+ Py_END_ALLOW_THREADS
350
+ }
351
+ }
352
+
342
353
static void
343
354
connection_dealloc (pysqlite_Connection * self )
344
355
{
@@ -348,7 +359,6 @@ connection_dealloc(pysqlite_Connection *self)
348
359
349
360
/* Clean up if user has not called .close() explicitly. */
350
361
connection_close (self );
351
- free_callback_contexts (self );
352
362
353
363
tp -> tp_free (self );
354
364
Py_DECREF (tp );
0 commit comments