Skip to content

Commit 70ec950

Browse files
committed
Extract out ErrorStatement and WorkerDriverAdapter, simplifying the
drivers.
1 parent ebe8d1b commit 70ec950

File tree

6 files changed

+285
-499
lines changed

6 files changed

+285
-499
lines changed

packages/better-sqlite3-driver/src/sync-driver.ts

Lines changed: 3 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import {
22
PrepareOptions,
33
ResetOptions,
4+
SqliteChanges,
45
SqliteDriverConnection,
5-
SqliteDriverConnectionPool,
66
SqliteDriverStatement,
77
SqliteParameterBinding,
8-
SqliteChanges,
98
SqliteStepResult,
109
SqliteValue,
1110
StepOptions,
@@ -14,85 +13,15 @@ import {
1413
import type * as bsqlite from 'better-sqlite3';
1514
import DatabaseConstructor from 'better-sqlite3';
1615

17-
import { mapError, ReadWriteConnectionPool } from '@sqlite-js/driver/util';
18-
import {
19-
InferBatchResult,
20-
SqliteBind,
21-
SqliteCommand,
22-
SqliteCommandResponse,
23-
SqliteCommandType,
24-
SqliteDriverError,
25-
SqliteFinalize,
26-
SqliteParse,
27-
SqliteParseResult,
28-
SqlitePrepare,
29-
SqliteReset,
30-
SqliteRun,
31-
SqliteStep
32-
} from '@sqlite-js/driver/worker_threads';
16+
import { ErrorStatement, mapError } from '@sqlite-js/driver/util';
17+
import { SqliteDriverError } from '@sqlite-js/driver/worker_threads';
3318
import { BetterSqliteDriverOptions } from './driver.js';
3419

3520
interface InternalStatement extends SqliteDriverStatement {
36-
getColumnsSync(): string[];
37-
stepSync(n?: number, options?: StepOptions): SqliteStepResult;
38-
runSync(options?: StepOptions): SqliteChanges;
39-
4021
readonly source: string;
41-
4222
readonly persisted: boolean;
4323
}
4424

45-
class ErrorStatement implements InternalStatement {
46-
readonly error: SqliteDriverError;
47-
readonly source: string;
48-
readonly persisted: boolean;
49-
50-
constructor(
51-
source: string,
52-
error: SqliteDriverError,
53-
options: PrepareOptions
54-
) {
55-
this.error = error;
56-
this.source = source;
57-
this.persisted = options.persist ?? false;
58-
}
59-
60-
getColumnsSync(): string[] {
61-
throw this.error;
62-
}
63-
stepSync(n?: number, options?: StepOptions): SqliteStepResult {
64-
throw this.error;
65-
}
66-
runSync(options?: StepOptions): SqliteChanges {
67-
throw this.error;
68-
}
69-
async getColumns(): Promise<string[]> {
70-
throw this.error;
71-
}
72-
bind(parameters: SqliteParameterBinding): void {
73-
// no-op
74-
}
75-
async step(n?: number, options?: StepOptions): Promise<SqliteStepResult> {
76-
throw this.error;
77-
}
78-
79-
async run(options?: StepOptions): Promise<SqliteChanges> {
80-
throw this.error;
81-
}
82-
83-
finalize(): void {
84-
// no-op
85-
}
86-
87-
reset(options?: ResetOptions): void {
88-
// no-op
89-
}
90-
91-
[Symbol.dispose](): void {
92-
// no-op
93-
}
94-
}
95-
9625
class BetterSqlitePreparedStatement implements InternalStatement {
9726
public statement: bsqlite.Statement;
9827
private options: PrepareOptions;
@@ -120,10 +49,6 @@ class BetterSqlitePreparedStatement implements InternalStatement {
12049
}
12150

12251
async getColumns(): Promise<string[]> {
123-
return this.getColumnsSync();
124-
}
125-
126-
getColumnsSync(): string[] {
12752
const existing = this.statement;
12853
if (existing.reader) {
12954
const columns = existing.columns().map((c) => c.name);
@@ -272,8 +197,6 @@ class BetterSqlitePreparedStatement implements InternalStatement {
272197

273198
export class BetterSqliteConnection implements SqliteDriverConnection {
274199
con: bsqlite.Database;
275-
private statements = new Map<number, InternalStatement>();
276-
277200
private changeStatement: bsqlite.Statement;
278201

279202
static open(
@@ -302,10 +225,6 @@ export class BetterSqliteConnection implements SqliteDriverConnection {
302225
}
303226

304227
async getLastChanges(): Promise<SqliteChanges> {
305-
return this._getLastChangesSync();
306-
}
307-
308-
_getLastChangesSync(): SqliteChanges {
309228
const r = this.changeStatement.get() as any;
310229
return {
311230
lastInsertRowId: r!.l,
@@ -314,15 +233,6 @@ export class BetterSqliteConnection implements SqliteDriverConnection {
314233
}
315234

316235
async close() {
317-
const remainingStatements = [...this.statements.values()].filter(
318-
(s) => !s.persisted
319-
);
320-
if (remainingStatements.length > 0) {
321-
const statement = remainingStatements[0];
322-
throw new Error(
323-
`${remainingStatements.length} statements not finalized. First: ${statement.source}`
324-
);
325-
}
326236
this.con.close();
327237
}
328238

@@ -335,115 +245,6 @@ export class BetterSqliteConnection implements SqliteDriverConnection {
335245
}
336246
}
337247

338-
private requireStatement(id: number) {
339-
const statement = this.statements.get(id);
340-
if (statement == null) {
341-
throw new Error(`statement not found: ${id}`);
342-
}
343-
return statement;
344-
}
345-
346-
private _prepare(command: SqlitePrepare) {
347-
const { id, sql } = command;
348-
const statement = this.prepare(sql, {
349-
bigint: command.bigint,
350-
persist: command.persist,
351-
rawResults: command.rawResults
352-
});
353-
const existing = this.statements.get(id);
354-
if (existing != null) {
355-
throw new Error(
356-
`Replacing statement ${id} without finalizing the previous one`
357-
);
358-
}
359-
this.statements.set(id, statement);
360-
}
361-
362-
private _parse(command: SqliteParse): SqliteParseResult {
363-
const { id } = command;
364-
const statement = this.requireStatement(id);
365-
return { columns: statement.getColumnsSync() };
366-
}
367-
368-
private _bind(command: SqliteBind): void {
369-
const { id, parameters } = command;
370-
const statement = this.requireStatement(id);
371-
statement.bind(parameters);
372-
}
373-
374-
private _step(command: SqliteStep): SqliteStepResult {
375-
const { id, n, requireTransaction } = command;
376-
const statement = this.requireStatement(id);
377-
return statement.stepSync(n, { requireTransaction });
378-
}
379-
380-
private _run(command: SqliteRun): SqliteChanges {
381-
const { id, requireTransaction } = command;
382-
const statement = this.requireStatement(id);
383-
return statement.runSync({ requireTransaction });
384-
}
385-
386-
private _reset(command: SqliteReset): void {
387-
const { id } = command;
388-
const statement = this.requireStatement(id);
389-
statement.reset(command);
390-
}
391-
392-
private _finalize(command: SqliteFinalize): void {
393-
const { id } = command;
394-
395-
const statement = this.statements.get(id);
396-
if (statement != null) {
397-
statement.finalize();
398-
this.statements.delete(id);
399-
}
400-
}
401-
402-
private _executeCommand(command: SqliteCommand): any {
403-
switch (command.type) {
404-
case SqliteCommandType.prepare:
405-
return this._prepare(command);
406-
case SqliteCommandType.bind:
407-
return this._bind(command);
408-
case SqliteCommandType.step:
409-
return this._step(command);
410-
case SqliteCommandType.run:
411-
return this._run(command);
412-
case SqliteCommandType.reset:
413-
return this._reset(command);
414-
case SqliteCommandType.finalize:
415-
return this._finalize(command);
416-
case SqliteCommandType.parse:
417-
return this._parse(command);
418-
case SqliteCommandType.changes:
419-
return this._getLastChangesSync();
420-
default:
421-
throw new Error(`Unknown command: ${command.type}`);
422-
}
423-
}
424-
425-
async execute<const T extends SqliteCommand[]>(
426-
commands: T
427-
): Promise<InferBatchResult<T>> {
428-
let results: SqliteCommandResponse[] = [];
429-
430-
for (let command of commands) {
431-
try {
432-
const result = this._executeCommand(command);
433-
results.push({ value: result });
434-
} catch (e: any) {
435-
results.push({
436-
error: mapError(e)
437-
});
438-
}
439-
}
440-
return results as InferBatchResult<T>;
441-
}
442-
443-
dispose(): void {
444-
// No-op
445-
}
446-
447248
onUpdate(
448249
listener: UpdateListener,
449250
options?:

0 commit comments

Comments
 (0)