diff --git a/bindings/wasm/integration-tests/tests/test.js b/bindings/wasm/integration-tests/tests/test.js index 6fd37b20f..5932e7f0e 100644 --- a/bindings/wasm/integration-tests/tests/test.js +++ b/bindings/wasm/integration-tests/tests/test.js @@ -30,6 +30,40 @@ test.serial("Statement.raw().all()", async (t) => { t.deepEqual(stmt.raw().all(), expected); }); +test.serial("Statement.raw().get()", async (t) => { + const db = t.context.db; + + const stmt = db.prepare("SELECT * FROM users"); + const expected = [ + 1, "Alice", "alice@example.org" + ]; + t.deepEqual(stmt.raw().get(), expected); + + const emptyStmt = db.prepare("SELECT * FROM users WHERE id = -1"); + t.is(emptyStmt.raw().get(), undefined); +}); + +test.serial("Statement.raw().iterate()", async (t) => { + const db = t.context.db; + + const stmt = db.prepare("SELECT * FROM users"); + const expected = [ + { done: false, value: [1, "Alice", "alice@example.org"] }, + { done: false, value: [2, "Bob", "bob@example.com"] }, + { done: true, value: undefined }, + ]; + + let iter = stmt.raw().iterate(); + t.is(typeof iter[Symbol.iterator], 'function'); + t.deepEqual(iter.next(), expected[0]) + t.deepEqual(iter.next(), expected[1]) + t.deepEqual(iter.next(), expected[2]) + + const emptyStmt = db.prepare("SELECT * FROM users WHERE id = -1"); + t.is(typeof emptyStmt[Symbol.iterator], 'undefined'); + t.throws(() => emptyStmt.next(), { instanceOf: TypeError }); +}); + const connect = async (path_opt) => { const path = path_opt ?? "hello.db"; const provider = process.env.PROVIDER; diff --git a/bindings/wasm/lib.rs b/bindings/wasm/lib.rs index 036a7ad1d..06a3a43ee 100644 --- a/bindings/wasm/lib.rs +++ b/bindings/wasm/lib.rs @@ -61,6 +61,21 @@ impl Statement { self } + pub fn get(&self) -> JsValue { + match self.inner.borrow_mut().step() { + Ok(limbo_core::RowResult::Row(row)) => { + let row_array = js_sys::Array::new(); + for value in row.values { + let value = to_js_value(value); + row_array.push(&value); + } + JsValue::from(row_array) + } + Ok(limbo_core::RowResult::IO) | Ok(limbo_core::RowResult::Done) => JsValue::UNDEFINED, + Err(e) => panic!("Error: {:?}", e), + } + } + pub fn all(&self) -> js_sys::Array { let array = js_sys::Array::new(); loop { @@ -80,6 +95,18 @@ impl Statement { } array } + + pub fn iterate(&self) -> JsValue { + let all = self.all(); + let iterator_fn = js_sys::Reflect::get(&all, &js_sys::Symbol::iterator()) + .expect("Failed to get iterator function") + .dyn_into::() + .expect("Symbol.iterator is not a function"); + + iterator_fn + .call0(&all) + .expect("Failed to call iterator function") + } } fn to_js_value(value: limbo_core::Value) -> JsValue {