quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit bcf81facaa8ee6f5bf40e44c52540943aa7dbf51
parent 90c15be14a45fa6ac5e7afb90f573141936a0a4c
Author: Florian Dold <dold@taler.net>
Date:   Sun,  9 Aug 2026 18:44:00 +0200

sqlite: reset getFirst statements before returning

Diffstat:
Mtart_module.c | 7++++---
Mtests/test_sqlite3_error.js | 32++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/tart_module.c b/tart_module.c @@ -2102,14 +2102,15 @@ static JSValue js_sqlite3_stmt_get_first(JSContext *ctx, JSValue this_val, goto fail; } ret_val = row_obj; - goto done; + goto reset; } case SQLITE_DONE: { ret_val = JS_UNDEFINED; - goto done; + goto reset; } default: ret_val = throw_sqlite3_error(ctx, db); + sqlite3_reset(stmt); goto done; } } @@ -2124,7 +2125,7 @@ done: return ret_val; fail: ret_val = JS_EXCEPTION; - goto done; + goto reset; } diff --git a/tests/test_sqlite3_error.js b/tests/test_sqlite3_error.js @@ -0,0 +1,32 @@ +import * as os from "os"; +import * as tart from "tart"; + +const dbPath = `/tmp/qtart-sqlite3-get-first-${Date.now()}.sqlite3`; +let db; +let stmt; + +try { + db = tart.sqlite3Open(dbPath); + tart.sqlite3Exec(db, "CREATE TABLE entries (value TEXT)"); + tart.sqlite3Exec(db, "INSERT INTO entries VALUES ('one')"); + + stmt = tart.sqlite3Prepare(db, "SELECT value FROM entries"); + const row = tart.sqlite3StmtGetFirst(stmt); + if (row?.value !== "one") { + throw Error(`unexpected first row: ${JSON.stringify(row)}`); + } + + // Changing into WAL fails while another statement on the connection is + // still active. sqlite3StmtGetFirst must reset its SELECT before returning. + tart.sqlite3Exec(db, "PRAGMA journal_mode = WAL"); +} finally { + if (stmt !== undefined) { + tart.sqlite3Finalize(stmt); + } + if (db !== undefined) { + tart.sqlite3Close(db); + } + os.remove(dbPath); + os.remove(`${dbPath}-wal`); + os.remove(`${dbPath}-shm`); +}