Skip to content

Commit

Permalink
Invoking better-sqlite3 through @miniflare/d1 instead
Browse files Browse the repository at this point in the history
  • Loading branch information
geelen committed Aug 12, 2022
1 parent 0563f66 commit f250653
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 51 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/d1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
},
"dependencies": {
"@miniflare/core": "2.6.0",
"@miniflare/shared": "2.6.0"
"@miniflare/shared": "2.6.0",
"@types/better-sqlite3": "^7.6.0"
},
"devDependencies": {
"@miniflare/shared-test": "2.6.0"
Expand Down
49 changes: 38 additions & 11 deletions packages/d1/src/database.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import path from "node:path";
import { performance } from "node:perf_hooks";
import { Storage } from "@miniflare/shared";
import type Database from "better-sqlite3";

import type {
Database as SqliteDB,
Options as SqliteOptions,
Statement as SqliteStatement,
} from "better-sqlite3";
import { npxImport, npxResolve } from "npx-import";

// Can't export typeof import(), so reproducing BetterSqlite3.DatabaseConstructor here
export interface DBConstructor {
new (filename: string | Buffer, options?: SqliteOptions): SqliteDB;
}
export type BindParams = any[] | [Record<string, any>];

function errorWithCause(message: string, e: unknown) {
Expand All @@ -10,11 +20,11 @@ function errorWithCause(message: string, e: unknown) {
}

export class Statement {
readonly #db: Database.Database;
readonly #db: SqliteDB;
readonly #query: string;
readonly #bindings: BindParams | undefined;

constructor(db: Database.Database, query: string, bindings?: BindParams) {
constructor(db: SqliteDB, query: string, bindings?: BindParams) {
this.#db = db;
this.#query = query;
this.#bindings = bindings;
Expand Down Expand Up @@ -61,7 +71,7 @@ export class Statement {
throw errorWithCause("D1_ALL_ERROR", e);
}
}
private static _all(statementWithBindings: Database.Statement) {
private static _all(statementWithBindings: SqliteStatement) {
try {
return statementWithBindings.all();
} catch (e: unknown) {
Expand All @@ -87,7 +97,7 @@ export class Statement {
throw errorWithCause("D1_FIRST_ERROR", e);
}
}
private static _first(statementWithBindings: Database.Statement) {
private static _first(statementWithBindings: SqliteStatement) {
return statementWithBindings.get();
}

Expand All @@ -110,34 +120,35 @@ export class Statement {
throw errorWithCause("D1_RUN_ERROR", e);
}
}
private static _run(statementWithBindings: Database.Statement) {
private static _run(statementWithBindings: SqliteStatement) {
return statementWithBindings.run();
}

async raw() {
const statementWithBindings = this.prepareAndBind();
return Statement._raw(statementWithBindings);
}
private static _raw(statementWithBindings: Database.Statement) {
private static _raw(statementWithBindings: SqliteStatement) {
return statementWithBindings.raw() as any;
}
}

function assert<T>(db: T | undefined): asserts db is T {
if (typeof db === "undefined")
throw new Error("D1 BetaDatabase must have await init() called!");
throw new Error("D1 BetaDatabase must have `await init()` called!");
}

export class BetaDatabase {
readonly #storage: Storage;
#db?: Database.Database;
#db?: SqliteDB;

constructor(storage: Storage) {
this.#storage = storage;
}

async init() {
this.#db = await this.#storage.getSqliteDatabase();
const dbPath = this.#storage.getSqliteDatabasePath();
this.#db = await createSQLiteDB(dbPath);
}

prepare(source: string) {
Expand Down Expand Up @@ -169,3 +180,19 @@ export class BetaDatabase {
throw new Error("DB.dump() not implemented locally!");
}
}

export async function createSQLiteDB(dbPath: string): Promise<SqliteDB> {
const { default: DatabaseConstructor } = await npxImport<{
default: DBConstructor;
}>("better-sqlite3@7.6.2");
return new DatabaseConstructor(dbPath, {
nativeBinding: getSQLiteNativeBindingLocation(npxResolve("better-sqlite3")),
});
}

export function getSQLiteNativeBindingLocation(sqliteResolvePath: string) {
return path.resolve(
path.dirname(sqliteResolvePath),
"../build/Release/better_sqlite3.node"
);
}
1 change: 0 additions & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"extends": "../../package.json"
},
"dependencies": {
"@types/better-sqlite3": "^7.6.0",
"ignore": "^5.1.8",
"kleur": "^4.1.4",
"npx-import": "^1.0.2"
Expand Down
11 changes: 1 addition & 10 deletions packages/shared/src/storage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import path from "node:path";
import type Database from "better-sqlite3";
import { Awaitable } from "./sync";

export interface StoredMeta<Meta = unknown> {
Expand Down Expand Up @@ -118,7 +116,7 @@ export abstract class Storage {
options: StorageListOptions,
skipMetadata: true
): Awaitable<StorageListResult<StoredKey>>;
async getSqliteDatabase(): Promise<Database.Database> {
getSqliteDatabasePath(): string {
throw new Error("D1 not implemented for this Storage class");
}

Expand Down Expand Up @@ -166,10 +164,3 @@ export interface StorageFactory {
storage(namespace: string, persist?: boolean | string): Awaitable<Storage>;
dispose?(): Awaitable<void>;
}

export function getSQLiteNativeBindingLocation(sqliteResolvePath: string) {
return path.resolve(
path.dirname(sqliteResolvePath),
"../build/Release/better_sqlite3.node"
);
}
14 changes: 2 additions & 12 deletions packages/storage-file/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@ import {
StoredMeta,
StoredValueMeta,
defaultClock,
getSQLiteNativeBindingLocation,
sanitisePath,
viewToArray,
} from "@miniflare/shared";
import { LocalStorage } from "@miniflare/storage-memory";
import type Database from "better-sqlite3";
import { npxImport, npxResolve } from "npx-import";
import {
deleteFile,
readFile,
Expand Down Expand Up @@ -107,16 +104,9 @@ export class FileStorage extends LocalStorage {
}
}

async getSqliteDatabase(): Promise<Database.Database> {
const { default: DatabaseConstructor } = await npxImport<{
default: typeof import("better-sqlite3");
}>("better-sqlite3@7.6.2");
getSqliteDatabasePath(): string {
fs.mkdirSync(path.dirname(this.root), { recursive: true });
return new DatabaseConstructor(this.root + ".sqlite3", {
nativeBinding: getSQLiteNativeBindingLocation(
npxResolve("better-sqlite3")
),
});
return this.root + ".sqlite3";
}

async getRangeMaybeExpired<Meta = unknown>(
Expand Down
14 changes: 2 additions & 12 deletions packages/storage-memory/src/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import {
StoredMeta,
StoredValueMeta,
defaultClock,
getSQLiteNativeBindingLocation,
millisToSeconds,
} from "@miniflare/shared";
import type Database from "better-sqlite3";
import { npxImport, npxResolve } from "npx-import";
import { listFilterMatch, listPaginate } from "./helpers";

export abstract class LocalStorage extends Storage {
Expand Down Expand Up @@ -120,14 +117,7 @@ export abstract class LocalStorage extends Storage {
return res;
}

async getSqliteDatabase(): Promise<Database.Database> {
const { default: DatabaseConstructor } = await npxImport<{
default: typeof import("better-sqlite3");
}>("better-sqlite3@7.6.2");
return new DatabaseConstructor(":memory:", {
nativeBinding: getSQLiteNativeBindingLocation(
npxResolve("better-sqlite3")
),
});
getSqliteDatabasePath(): string {
return ":memory:";
}
}

0 comments on commit f250653

Please sign in to comment.