import type { KyselyPlugin, QueryResult } from "kysely"; import { type IGenericSqlite, type Promisable, parseBigInt, buildQueryFn, GenericSqliteDialect, } from "kysely-generic-sqlite"; import { SqliteConnection } from "./SqliteConnection"; import type { ConnQuery, ConnQueryResults, Features } from "../Connection"; import type { MaybePromise } from "bknd"; export type { IGenericSqlite }; export type TStatement = { sql: string; parameters?: any[] | readonly any[] }; export interface IGenericCustomSqlite extends IGenericSqlite { batch?: (stmts: TStatement[]) => Promisable[]>; } export type GenericSqliteConnectionConfig = { name?: string; additionalPlugins?: KyselyPlugin[]; excludeTables?: string[]; onCreateConnection?: (db: Database) => MaybePromise; supports?: Partial; }; export class GenericSqliteConnection extends SqliteConnection { override name = "generic-sqlite"; #executor: IGenericCustomSqlite | undefined; constructor( public db: DB, private executor: () => Promisable>, config?: GenericSqliteConnectionConfig, ) { super({ dialect: GenericSqliteDialect, dialectArgs: [ executor, config?.onCreateConnection && typeof config.onCreateConnection === "function" ? (c: any) => config.onCreateConnection?.(c.db.db as any) : undefined, ], additionalPlugins: config?.additionalPlugins, excludeTables: config?.excludeTables, }); this.client = db; if (config?.name) { this.name = config.name; } if (config?.supports) { for (const [key, value] of Object.entries(config.supports)) { if (value !== undefined) { this.supported[key] = value; } } } } private async getExecutor() { if (!this.#executor) { this.#executor = await this.executor(); } return this.#executor; } override async executeQueries(...qbs: O): Promise> { const executor = await this.getExecutor(); if (!executor.batch) { return super.executeQueries(...qbs); } const compiled = this.getCompiled(...qbs); const stms: TStatement[] = compiled.map((q) => { return { sql: q.sql, parameters: q.parameters as any[], }; }); const results = await executor.batch(stms); return this.withTransformedRows(results) as any; } } 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, };