Skip to content

Commit b56e00c

Browse files
committed
feat: improve iterator
1 parent ee9fd6f commit b56e00c

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

playground/src/runSQL.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export async function runSQLStream(
2222
export async function runIterator(
2323
core: SQLiteDBCore,
2424
): Promise<void> {
25-
const sql = 'INSERT INTO t1 VALUES(100, 19147, \'nineteen thousand one hundred forty-seven\'), (200, 26008, \'twenty-six thousand eight\'), (300, 46582, \'forty-six thousand five hundred eighty-two\');select * from t1;'
25+
const sql = 'INSERT INTO t1 VALUES(100, 19147, \'nineteen thousand one hundred forty-seven\'), (200, 26008, \'twenty-six thousand eight\'), (300, 46582, \'forty-six thousand five hundred eighty-two\') returning *;'
2626
const it = iterator(core, sql)
2727
for await (const row of it) {
2828
console.log('[iterator]', row)

src/utils.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { BaseStorageOptions, SQLiteDBCore } from './types'
2-
import { SQLITE_DETERMINISTIC, SQLITE_DIRECTONLY, SQLITE_UTF8 } from 'wa-sqlite'
2+
import { SQLITE_DETERMINISTIC, SQLITE_DIRECTONLY, SQLITE_OK, SQLITE_UTF8 } from 'wa-sqlite'
33
import { SQLITE_ROW } from 'wa-sqlite/src/sqlite-constants.js'
44
import { importDatabase } from './io'
55

@@ -225,16 +225,37 @@ export async function* iterator(
225225
core: SQLiteDBCore,
226226
sql: string,
227227
parameters?: SQLiteCompatibleType[],
228-
): AsyncIterableIterator<Record<string, SQLiteCompatibleType>> {
228+
chunkSize = 1,
229+
): AsyncIterableIterator<Record<string, SQLiteCompatibleType>[]> {
229230
const { sqlite, pointer } = core
231+
// eslint-disable-next-line unicorn/no-new-array
232+
let cache = new Array(chunkSize)
230233
for await (const stmt of sqlite.statements(pointer, sql)) {
231234
if (parameters?.length) {
232235
sqlite.bind_collection(stmt, parameters)
233236
}
237+
let idx = 0
234238
const cols = sqlite.column_names(stmt)
235-
while (await sqlite.step(stmt) === SQLITE_ROW) {
236-
const row = sqlite.row(stmt)
237-
yield Object.fromEntries(cols.map((key, i) => [key, row[i]]))
239+
while (1) {
240+
const result = await sqlite.step(stmt)
241+
if (result === SQLITE_ROW) {
242+
const row = sqlite.row(stmt)
243+
cache[idx] = Object.fromEntries(cols.map((key, i) => [key, row[i]]))
244+
if (++idx === chunkSize) {
245+
yield cache.slice(0, idx)
246+
idx = 0
247+
}
248+
} else if (result === SQLITE_OK) {
249+
if (++idx === chunkSize) {
250+
yield []
251+
}
252+
} else {
253+
if (idx > 0) {
254+
yield cache.slice(0, idx)
255+
}
256+
break
257+
}
238258
}
239259
}
260+
cache = undefined!
240261
}

0 commit comments

Comments
 (0)