Skip to content

Commit

Permalink
Fix Statement.run() for SELECT statements
Browse files Browse the repository at this point in the history
The `better-sqlite3` API allows `run()` on all types of statements.
However, we currently use `libsql` crate's `Statement::execute()`, which
returns an error if a statement results in rows. Fix the compatibility
issue by switching to the new `Statement::run()` method in `libsql`.
  • Loading branch information
penberg committed Jun 27, 2024
1 parent 1ab07e7 commit 2df0e5e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
8 changes: 8 additions & 0 deletions integration-tests/tests/sync.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ test.serial("Statement.prepare() error", async (t) => {
});
});

test.serial("Statement.run() returning rows", async (t) => {
const db = t.context.db;

const stmt = db.prepare("SELECT 1");
const info = stmt.run();
t.is(info.changes, 0);
});

test.serial("Statement.run() [positional]", async (t) => {
const db = t.context.db;

Expand Down
21 changes: 16 additions & 5 deletions src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,27 @@ impl Statement {

pub fn js_run(mut cx: FunctionContext) -> JsResult<JsValue> {
let stmt: Handle<'_, JsBox<Statement>> = cx.this()?;
let raw_conn = stmt.conn.clone();
let total_changes_before = raw_conn.blocking_lock().total_changes();
let params = cx.argument::<JsValue>(0)?;
let params = convert_params(&mut cx, &stmt, params)?;
let mut raw_stmt = stmt.stmt.blocking_lock();
raw_stmt.reset();
let fut = raw_stmt.execute(params);
let fut = raw_stmt.run(params);
let rt = runtime(&mut cx)?;
let result = rt.block_on(fut);
let changes = result.or_else(|err| throw_libsql_error(&mut cx, err))?;
let raw_conn = stmt.conn.clone();
let last_insert_rowid = raw_conn.blocking_lock().last_insert_rowid();
rt.block_on(fut)
.or_else(|err| throw_libsql_error(&mut cx, err))?;
let (changes, last_insert_rowid) = {
let raw_conn = stmt.conn.clone();
let raw_conn = raw_conn.blocking_lock();
let changes = if raw_conn.total_changes() == total_changes_before {
0
} else {
raw_conn.changes()
};
let last_insert_rowid = raw_conn.last_insert_rowid();
(changes, last_insert_rowid)
};
let info = cx.empty_object();
let changes = cx.number(changes as f64);
info.set(&mut cx, "changes", changes)?;
Expand Down

0 comments on commit 2df0e5e

Please sign in to comment.