From 3338804c3457fbc218842b430ba5f64f8e4b4749 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 14 Jun 2025 16:58:38 +0200 Subject: [PATCH] simplify and export generic sqlite functions --- .../bun/connection/BunSqliteConnection.ts | 54 ++++++-------- .../node/connection/NodeSqliteConnection.ts | 73 ++++++++----------- app/src/data/connection/index.ts | 1 - .../sqlite/GenericSqliteConnection.ts | 20 ++++- app/src/data/index.ts | 7 ++ 5 files changed, 81 insertions(+), 74 deletions(-) diff --git a/app/src/adapter/bun/connection/BunSqliteConnection.ts b/app/src/adapter/bun/connection/BunSqliteConnection.ts index f884249..f4f3f1f 100644 --- a/app/src/adapter/bun/connection/BunSqliteConnection.ts +++ b/app/src/adapter/bun/connection/BunSqliteConnection.ts @@ -1,9 +1,7 @@ import { Database } from "bun:sqlite"; import { - buildQueryFn, - GenericSqliteConnection, - parseBigInt, - type IGenericSqlite, + genericSqlite, + type GenericSqliteConnection, } from "data/connection/sqlite/GenericSqliteConnection"; export type BunSqliteConnection = GenericSqliteConnection; @@ -11,39 +9,35 @@ export type BunSqliteConnectionConfig = { database: Database; }; -function bunSqliteExecutor(db: Database, cache: boolean): IGenericSqlite { - const fn = cache ? "query" : "prepare"; - const getStmt = (sql: string) => db[fn](sql); - - return { - db, - query: buildQueryFn({ - all: (sql, parameters) => getStmt(sql).all(...(parameters || [])), - run: (sql, parameters) => { - const { changes, lastInsertRowid } = getStmt(sql).run(...(parameters || [])); - return { - insertId: parseBigInt(lastInsertRowid), - numAffectedRows: parseBigInt(changes), - }; - }, - }), - close: () => db.close(), - }; -} - export function bunSqlite(config?: BunSqliteConnectionConfig | { url: string }) { - let database: Database; + let db: Database; if (config) { if ("database" in config) { - database = config.database; + db = config.database; } else { - database = new Database(config.url); + db = new Database(config.url); } } else { - database = new Database(":memory:"); + db = new Database(":memory:"); } - return new GenericSqliteConnection(database, () => bunSqliteExecutor(database, false), { - name: "bun-sqlite", + return genericSqlite("bun-sqlite", db, (utils) => { + //const fn = cache ? "query" : "prepare"; + const getStmt = (sql: string) => db.prepare(sql); + + return { + db, + query: utils.buildQueryFn({ + all: (sql, parameters) => getStmt(sql).all(...(parameters || [])), + run: (sql, parameters) => { + const { changes, lastInsertRowid } = getStmt(sql).run(...(parameters || [])); + return { + insertId: utils.parseBigInt(lastInsertRowid), + numAffectedRows: utils.parseBigInt(changes), + }; + }, + }), + close: () => db.close(), + }; }); } diff --git a/app/src/adapter/node/connection/NodeSqliteConnection.ts b/app/src/adapter/node/connection/NodeSqliteConnection.ts index 8fdc630..60ad9df 100644 --- a/app/src/adapter/node/connection/NodeSqliteConnection.ts +++ b/app/src/adapter/node/connection/NodeSqliteConnection.ts @@ -1,57 +1,48 @@ -import { - buildQueryFn, - GenericSqliteConnection, - parseBigInt, - type IGenericSqlite, -} from "../../../data/connection/sqlite/GenericSqliteConnection"; +import { genericSqlite } from "data/connection/sqlite/GenericSqliteConnection"; import { DatabaseSync } from "node:sqlite"; export type NodeSqliteConnectionConfig = { database: DatabaseSync; }; -function nodeSqliteExecutor(db: DatabaseSync): IGenericSqlite { - const getStmt = (sql: string) => { - const stmt = db.prepare(sql); - //stmt.setReadBigInts(true); - return stmt; - }; - - return { - db, - query: buildQueryFn({ - all: (sql, parameters = []) => getStmt(sql).all(...parameters), - run: (sql, parameters = []) => { - const { changes, lastInsertRowid } = getStmt(sql).run(...parameters); - return { - insertId: parseBigInt(lastInsertRowid), - numAffectedRows: parseBigInt(changes), - }; - }, - }), - close: () => db.close(), - iterator: (isSelect, sql, parameters = []) => { - if (!isSelect) { - throw new Error("Only support select in stream()"); - } - return getStmt(sql).iterate(...parameters) as any; - }, - }; -} - export function nodeSqlite(config?: NodeSqliteConnectionConfig | { url: string }) { - let database: DatabaseSync; + let db: DatabaseSync; if (config) { if ("database" in config) { - database = config.database; + db = config.database; } else { - database = new DatabaseSync(config.url); + db = new DatabaseSync(config.url); } } else { - database = new DatabaseSync(":memory:"); + db = new DatabaseSync(":memory:"); } - return new GenericSqliteConnection(database, () => nodeSqliteExecutor(database), { - name: "node-sqlite", + return genericSqlite("node-sqlite", db, (utils) => { + const getStmt = (sql: string) => { + const stmt = db.prepare(sql); + //stmt.setReadBigInts(true); + return stmt; + }; + + return { + db, + query: utils.buildQueryFn({ + all: (sql, parameters = []) => getStmt(sql).all(...parameters), + run: (sql, parameters = []) => { + const { changes, lastInsertRowid } = getStmt(sql).run(...parameters); + return { + insertId: utils.parseBigInt(lastInsertRowid), + numAffectedRows: utils.parseBigInt(changes), + }; + }, + }), + close: () => db.close(), + iterator: (isSelect, sql, parameters = []) => { + if (!isSelect) { + throw new Error("Only support select in stream()"); + } + return getStmt(sql).iterate(...parameters) as any; + }, + }; }); } diff --git a/app/src/data/connection/index.ts b/app/src/data/connection/index.ts index 9bd285e..a55d135 100644 --- a/app/src/data/connection/index.ts +++ b/app/src/data/connection/index.ts @@ -11,7 +11,6 @@ export { } from "./Connection"; // sqlite -//export { libsql, LibsqlConnection, type LibSqlCredentials } from "./sqlite/LibsqlConnection"; export { SqliteConnection } from "./sqlite/SqliteConnection"; export { SqliteIntrospector } from "./sqlite/SqliteIntrospector"; export { SqliteLocalConnection } from "./sqlite/SqliteLocalConnection"; diff --git a/app/src/data/connection/sqlite/GenericSqliteConnection.ts b/app/src/data/connection/sqlite/GenericSqliteConnection.ts index d9abc5f..5bd4543 100644 --- a/app/src/data/connection/sqlite/GenericSqliteConnection.ts +++ b/app/src/data/connection/sqlite/GenericSqliteConnection.ts @@ -10,6 +10,7 @@ import { import { SqliteConnection } from "./SqliteConnection"; import type { Features } from "../Connection"; +export type { IGenericSqlite }; export type GenericSqliteConnectionConfig = { name: string; additionalPlugins?: KyselyPlugin[]; @@ -18,8 +19,6 @@ export type GenericSqliteConnectionConfig = { supports?: Partial; }; -export { parseBigInt, buildQueryFn, GenericSqliteDialect, type IGenericSqlite }; - export class GenericSqliteConnection extends SqliteConnection { override name = "generic-sqlite"; @@ -47,3 +46,20 @@ export class GenericSqliteConnection extends SqliteConnection } } } + +export function genericSqlite( + name: string, + db: DB, + executor: (utils: typeof genericSqliteUtils) => Promisable>, + config?: GenericSqliteConnectionConfig, +) { + return new GenericSqliteConnection(db, () => executor(genericSqliteUtils), { + name, + ...config, + }); +} + +export const genericSqliteUtils = { + parseBigInt, + buildQueryFn, +}; diff --git a/app/src/data/index.ts b/app/src/data/index.ts index 5069fce..9fb5a35 100644 --- a/app/src/data/index.ts +++ b/app/src/data/index.ts @@ -29,3 +29,10 @@ export { MutatorEvents, RepositoryEvents }; export * as DataPermissions from "./permissions"; export { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField"; + +export { libsql } from "./connection/sqlite/LibsqlConnection"; +export { + genericSqlite, + genericSqliteUtils, + type GenericSqliteConnection, +} from "./connection/sqlite/GenericSqliteConnection";