simplify and export generic sqlite functions

This commit is contained in:
dswbx
2025-06-14 16:58:38 +02:00
parent 6b3ac9e6e2
commit 3338804c34
5 changed files with 81 additions and 74 deletions

View File

@@ -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<Database>;
@@ -11,39 +9,35 @@ export type BunSqliteConnectionConfig = {
database: Database;
};
function bunSqliteExecutor(db: Database, cache: boolean): IGenericSqlite<Database> {
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(),
};
});
}

View File

@@ -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<DatabaseSync> {
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;
},
};
});
}

View File

@@ -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";

View File

@@ -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<Features>;
};
export { parseBigInt, buildQueryFn, GenericSqliteDialect, type IGenericSqlite };
export class GenericSqliteConnection<DB = unknown> extends SqliteConnection<DB> {
override name = "generic-sqlite";
@@ -47,3 +46,20 @@ export class GenericSqliteConnection<DB = unknown> extends SqliteConnection<DB>
}
}
}
export function genericSqlite<DB>(
name: string,
db: DB,
executor: (utils: typeof genericSqliteUtils) => Promisable<IGenericSqlite<DB>>,
config?: GenericSqliteConnectionConfig,
) {
return new GenericSqliteConnection(db, () => executor(genericSqliteUtils), {
name,
...config,
});
}
export const genericSqliteUtils = {
parseBigInt,
buildQueryFn,
};

View File

@@ -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";