@@ -42,6 +42,16 @@ inline TursoStmtHandle *to_turso_stmt(sqlite3_stmt *statement) {
4242 return reinterpret_cast <TursoStmtHandle *>(statement);
4343}
4444
45+ inline turso_connection_t *require_turso_connection (TursoDbHandle *handle,
46+ const std::string &context) {
47+ if (handle == nullptr || handle->connection == nullptr ) {
48+ throw std::runtime_error (" [op-sqlite][turso] " + context +
49+ " : invalid database connection" );
50+ }
51+
52+ return handle->connection ;
53+ }
54+
4555void throw_if_turso_error (turso_status_code_t code, const char *error,
4656 const std::string &context) {
4757 if (code == TURSO_OK || code == TURSO_ROW || code == TURSO_DONE) {
@@ -157,11 +167,12 @@ std::string opsqlite_get_db_path(std::string const &db_name,
157167sqlite3 *opsqlite_open (std::string const &name, std::string const &path,
158168 [[maybe_unused]] std::string const &crsqlite_path,
159169 [[maybe_unused]] std::string const &sqlite_vec_path) {
160- std::string final_path = opsqlite_get_db_path (name, path);
170+ auto *handle = new TursoDbHandle ();
171+ handle->path = opsqlite_get_db_path (name, path);
161172
162173 turso_database_config_t db_config = {
163174 .async_io = 0 ,
164- .path = final_path .c_str (),
175+ .path = handle-> path .c_str (),
165176 .experimental_features = nullptr ,
166177 .vfs = nullptr ,
167178 .encryption_cipher = nullptr ,
@@ -171,21 +182,33 @@ sqlite3 *opsqlite_open(std::string const &name, std::string const &path,
171182 const char *error = nullptr ;
172183 const turso_database_t *database = nullptr ;
173184
174- throw_if_turso_error (
175- turso_database_new (&db_config, &database, &error), error,
176- " create database at " + final_path);
177- throw_if_turso_error (turso_database_open (database, &error), error,
178- " open database at " + final_path);
185+ try {
186+ throw_if_turso_error (
187+ turso_database_new (&db_config, &database, &error), error,
188+ " create database at " + handle->path );
189+ throw_if_turso_error (turso_database_open (database, &error), error,
190+ " open database at " + handle->path );
191+
192+ turso_connection_t *connection = nullptr ;
193+ throw_if_turso_error (
194+ turso_database_connect (database, &connection, &error), error,
195+ " connect database at " + handle->path );
196+
197+ handle->database = database;
198+ handle->connection = connection;
199+ } catch (...) {
200+ if (handle->connection != nullptr ) {
201+ turso_connection_deinit (handle->connection );
202+ handle->connection = nullptr ;
203+ }
179204
180- turso_connection_t *connection = nullptr ;
181- throw_if_turso_error (
182- turso_database_connect (database, &connection, &error), error,
183- " connect database at " + final_path);
205+ if (database != nullptr ) {
206+ turso_database_deinit (database);
207+ }
184208
185- auto *handle = new TursoDbHandle ();
186- handle->database = database;
187- handle->connection = connection;
188- handle->path = final_path;
209+ delete handle;
210+ throw ;
211+ }
189212
190213 return reinterpret_cast <sqlite3 *>(handle);
191214}
@@ -240,7 +263,8 @@ sqlite3_stmt *opsqlite_prepare_statement(sqlite3 *db,
240263 const char *error = nullptr ;
241264
242265 throw_if_turso_error (turso_connection_prepare_single (
243- handle->connection , query.c_str (), &statement, &error),
266+ require_turso_connection (handle, " prepare statement" ),
267+ query.c_str (), &statement, &error),
244268 error, " prepare statement" );
245269
246270 auto *stmt_handle = new TursoStmtHandle ();
@@ -344,8 +368,8 @@ BridgeResult opsqlite_execute_prepared_statement(
344368 reset_statement (stmt->statement );
345369
346370 return {.affectedRows = changes,
347- .insertId = static_cast <double >(
348- turso_connection_last_insert_rowid (db_handle-> connection ))};
371+ .insertId = static_cast <double >( turso_connection_last_insert_rowid (
372+ require_turso_connection (db_handle, " last_insert_rowid " ) ))};
349373}
350374
351375BridgeResult opsqlite_execute (sqlite3 *db, std::string const &query,
@@ -361,9 +385,9 @@ BridgeResult opsqlite_execute(sqlite3 *db, std::string const &query,
361385 turso_statement_t *statement = nullptr ;
362386 size_t tail = 0 ;
363387
364- auto code = turso_connection_prepare_first (db_handle-> connection ,
365- query. c_str () + offset ,
366- &statement, &tail, &error);
388+ auto code = turso_connection_prepare_first (
389+ require_turso_connection (db_handle, " prepare statement in batch execute " ) ,
390+ query. c_str () + offset, &statement, &tail, &error);
367391 throw_if_turso_error (code, error, " prepare statement in batch execute" );
368392
369393 if (tail == 0 ) {
@@ -439,8 +463,8 @@ BridgeResult opsqlite_execute(sqlite3 *db, std::string const &query,
439463 }
440464
441465 return {.affectedRows = changes,
442- .insertId = static_cast <double >(
443- turso_connection_last_insert_rowid (db_handle-> connection )),
466+ .insertId = static_cast <double >( turso_connection_last_insert_rowid (
467+ require_turso_connection (db_handle, " last_insert_rowid " ) )),
444468 .rows = std::move (rows),
445469 .column_names = std::move (column_names)};
446470}
0 commit comments