Skip to content

Commit 3953fdb

Browse files
committed
async iteraertor
1 parent 5adf650 commit 3953fdb

File tree

6 files changed

+59
-33
lines changed

6 files changed

+59
-33
lines changed

index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface RunResult {
1212
duration: number
1313
lastInsertRowid: number
1414
}
15+
export declare function iteratorNextSync(iter: RowsIterator): Record
1516
export declare class SqliteError {
1617
message: string
1718
code: string
@@ -48,7 +49,7 @@ export declare class Statement {
4849
interrupt(): void
4950
}
5051
export declare class RowsIterator {
51-
next(): Record
52+
next(): Promise<Record>
5253
}
5354
export declare class Record {
5455
get value(): unknown

index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,12 @@ if (!nativeBinding) {
310310
throw new Error(`Failed to load native binding`)
311311
}
312312

313-
const { SqliteError, Database, databasePrepareSync, Statement, RowsIterator, Record } = nativeBinding
313+
const { SqliteError, Database, databasePrepareSync, Statement, RowsIterator, iteratorNextSync, Record } = nativeBinding
314314

315315
module.exports.SqliteError = SqliteError
316316
module.exports.Database = Database
317317
module.exports.databasePrepareSync = databasePrepareSync
318318
module.exports.Statement = Statement
319319
module.exports.RowsIterator = RowsIterator
320+
module.exports.iteratorNextSync = iteratorNextSync
320321
module.exports.Record = Record

integration-tests/tests/async.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ test.serial("Statement.iterate() [empty]", async (t) => {
113113

114114
const stmt = await db.prepare("SELECT * FROM users WHERE id = 0");
115115
const it = await stmt.iterate();
116-
t.is(it.next().done, true);
116+
t.is((await it.next()).done, true);
117117
});
118118

119119
test.serial("Statement.iterate()", async (t) => {
@@ -122,7 +122,7 @@ test.serial("Statement.iterate()", async (t) => {
122122
const stmt = await db.prepare("SELECT * FROM users");
123123
const expected = [1, 2];
124124
var idx = 0;
125-
for (const row of await stmt.iterate()) {
125+
for await (const row of await stmt.iterate()) {
126126
t.is(row.id, expected[idx++]);
127127
}
128128
});

promise.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,18 @@ class Statement {
264264
async iterate(...bindParameters) {
265265
try {
266266
const it = await this.stmt.iterate(...bindParameters);
267-
it[Symbol.iterator] = function() { return this; };
268-
return it;
267+
return {
268+
next() {
269+
return it.next();
270+
},
271+
[Symbol.asyncIterator]() {
272+
return {
273+
next() {
274+
return it.next();
275+
}
276+
};
277+
}
278+
};
269279
} catch (err) {
270280
throw convertError(err);
271281
}
@@ -281,7 +291,7 @@ class Statement {
281291
const result = [];
282292
const iterator = await this.iterate(...bindParameters);
283293
let next;
284-
while (!(next = iterator.next()).done) {
294+
while (!(next = await iterator.next()).done) {
285295
result.push(next.value);
286296
}
287297
return result;

src/lib.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod auth;
77
#[macro_use]
88
extern crate napi_derive;
99

10+
use libsql::Row;
1011
use napi::bindgen_prelude::{Array, FromNapiValue, ToNapiValue};
1112
use napi::{Env, JsUnknown, Result, ValueType};
1213
use once_cell::sync::OnceCell;
@@ -803,33 +804,40 @@ impl RowsIterator {
803804
}
804805

805806
#[napi]
806-
pub fn next(&self, env: Env) -> Result<Record> {
807-
let rt = runtime()?;
807+
pub async fn next(&self) -> Result<Record> {
808+
let column_names = self.column_names.clone();
809+
let safe_ints = self.safe_ints;
810+
let raw = self.raw;
811+
let pluck = self.pluck;
808812
let rows = self.rows.clone();
809-
rt.block_on(async move {
810-
let mut rows = rows.lock().await;
811-
let next_row = rows.next().await.map_err(Error::from)?;
812-
let record = match next_row {
813-
Some(row) => Record {
814-
column_names: self.column_names.clone(),
815-
row: Some(row),
816-
safe_ints: self.safe_ints,
817-
raw: self.raw,
818-
pluck: self.pluck,
819-
},
820-
None => Record {
821-
column_names: self.column_names.clone(),
822-
row: None,
823-
safe_ints: self.safe_ints,
824-
raw: self.raw,
825-
pluck: self.pluck,
826-
},
827-
};
828-
Ok(record)
829-
})
813+
let mut rows = rows.lock().await;
814+
let next_row = rows.next().await.map_err(Error::from)?;
815+
let record = match next_row {
816+
Some(row) => Record {
817+
column_names,
818+
row: Some(row),
819+
safe_ints,
820+
raw,
821+
pluck,
822+
},
823+
None => Record {
824+
column_names,
825+
row: None,
826+
safe_ints,
827+
raw,
828+
pluck,
829+
},
830+
};
831+
Ok(record)
830832
}
831833
}
832834

835+
#[napi]
836+
pub fn iterator_next_sync(iter: &RowsIterator) -> Result<Record> {
837+
let rt = runtime()?;
838+
rt.block_on(async move { iter.next().await })
839+
}
840+
833841
#[napi]
834842
pub struct Record {
835843
column_names: Vec<std::ffi::CString>,

wrapper.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use strict";
22

3-
const { Database: NativeDb, databasePrepareSync } = require("./index.js");
3+
const { Database: NativeDb, databasePrepareSync, iteratorNextSync } = require("./index.js");
44
const SqliteError = require("./sqlite-error.js");
55
const Authorization = require("./auth");
66

@@ -264,8 +264,14 @@ class Statement {
264264
iterate(...bindParameters) {
265265
try {
266266
const it = this.stmt.iterateSync(...bindParameters);
267-
it[Symbol.iterator] = function() { return this; };
268-
return it;
267+
return {
268+
next: () => iteratorNextSync(it),
269+
[Symbol.iterator]() {
270+
return {
271+
next: () => iteratorNextSync(it),
272+
}
273+
},
274+
};
269275
} catch (err) {
270276
throw convertError(err);
271277
}

0 commit comments

Comments
 (0)