diff --git a/bindings/javascript/__test__/better-sqlite3.spec.mjs b/bindings/javascript/__test__/better-sqlite3.spec.mjs index 288f62a1a..b0a247cfd 100644 --- a/bindings/javascript/__test__/better-sqlite3.spec.mjs +++ b/bindings/javascript/__test__/better-sqlite3.spec.mjs @@ -3,28 +3,35 @@ import test from "ava"; import Database from "better-sqlite3"; test("Open in-memory database", async (t) => { - const [db] = await connect(":memory:"); - t.is(db.memory, true); + const [db] = await connect(":memory:"); + t.is(db.memory, true); }); test("Statement.get() returns data", async (t) => { - const [db] = await connect(":memory:"); - const stmt = db.prepare("SELECT 1"); - const result = stmt.get(); - t.is(result["1"], 1); - const result2 = stmt.get(); - t.is(result2["1"], 1); + const [db] = await connect(":memory:"); + const stmt = db.prepare("SELECT 1"); + const result = stmt.get(); + t.is(result["1"], 1); + const result2 = stmt.get(); + t.is(result2["1"], 1); }); test("Statement.get() returns undefined when no data", async (t) => { - const [db] = await connect(":memory:"); - const stmt = db.prepare("SELECT 1 WHERE 1 = 2"); - const result = stmt.get(); - t.is(result, undefined); + const [db] = await connect(":memory:"); + const stmt = db.prepare("SELECT 1 WHERE 1 = 2"); + const result = stmt.get(); + t.is(result, undefined); +}); + +test("Statement.run() returns correct result object", async (t) => { + const [db] = await connect(":memory:"); + db.prepare("CREATE TABLE users (name TEXT)").run(); + const rows = db.prepare("INSERT INTO users (name) VALUES (?)").run("Alice"); + t.deepEqual(rows, { changes: 1, lastInsertRowid: 1 }); }); const connect = async (path) => { - const db = new Database(path); - return [db]; + const db = new Database(path); + return [db]; }; diff --git a/bindings/javascript/__test__/limbo.spec.mjs b/bindings/javascript/__test__/limbo.spec.mjs index fd3b5015b..ee24139fb 100644 --- a/bindings/javascript/__test__/limbo.spec.mjs +++ b/bindings/javascript/__test__/limbo.spec.mjs @@ -24,6 +24,16 @@ test("Statement.get() returns null when no data", async (t) => { t.is(result, undefined); }); +// run() isn't 100% compatible with better-sqlite3 +// it should return a result object, not a row object +test("Statement.run() returns correct result object", async (t) => { + const [db] = await connect(":memory:"); + db.prepare("CREATE TABLE users (name TEXT)").run(); + db.prepare("INSERT INTO users (name) VALUES (?)").run(["Alice"]); + let rows = db.prepare("SELECT * FROM users").all() + t.deepEqual(rows, [{ name: "Alice" }]); +}); + const connect = async (path) => { const db = new Database(path); return [db]; diff --git a/bindings/javascript/index.d.ts b/bindings/javascript/index.d.ts index 322dfe84d..99433b962 100644 --- a/bindings/javascript/index.d.ts +++ b/bindings/javascript/index.d.ts @@ -3,11 +3,41 @@ /* auto-generated by NAPI-RS */ +export interface Options { + readonly: boolean + fileMustExist: boolean + timeout: number +} export declare class Database { memory: boolean - constructor(path: string) + readonly: boolean + inTransaction: boolean + open: boolean + name: string + constructor(path: string, options?: Options | undefined | null) prepare(sql: string): Statement + transaction(): void + pragma(): void + backup(): void + serialize(): void + function(): void + aggregate(): void + table(): void + loadExtension(): void } export declare class Statement { - get(): NapiResult + database: Database + source: string + reader: boolean + readonly: boolean + busy: boolean + get(): unknown + all(): NapiResult + run(args: Array): void + static iterate(): void + static pluck(): void + static expand(): void + static raw(): void + static columns(): void + static bind(): void } diff --git a/bindings/javascript/src/lib.rs b/bindings/javascript/src/lib.rs index 79ba6805e..2a8bf0c09 100644 --- a/bindings/javascript/src/lib.rs +++ b/bindings/javascript/src/lib.rs @@ -1,6 +1,6 @@ #![deny(clippy::all)] -use std::cell::RefCell; +use std::cell::{RefCell, RefMut}; use std::num::NonZeroUsize; use std::rc::Rc; @@ -189,7 +189,8 @@ impl Statement { } } - self.internal_all(env) + let stmt = self.inner.borrow_mut(); + self.internal_all(env, stmt) } #[napi] @@ -202,12 +203,14 @@ impl Statement { let mut stmt = self.inner.borrow_mut(); stmt.reset(); - self.internal_all(env) + self.internal_all(env, stmt) } - fn internal_all(&self, env: Env) -> napi::Result { - let mut stmt = self.inner.borrow_mut(); - + fn internal_all( + &self, + env: Env, + mut stmt: RefMut<'_, limbo_core::Statement>, + ) -> napi::Result { let mut results = env.create_empty_array()?; let mut index = 0; loop {