kysely-generic-sqlite
Version:
Generic kysely dialect for SQLite, support run in main thread or worker
157 lines (152 loc) • 4.57 kB
JavaScript
;
var kysely = require('kysely');
// src/base.ts
var BaseSqliteDialect = class {
/**
* Base class that implements {@link Dialect}
* @param create function that create {@link Driver}
*/
constructor(create) {
this.createDriver = create;
}
createDriver;
createQueryCompiler() {
return new kysely.SqliteQueryCompiler();
}
createAdapter() {
return new kysely.SqliteAdapter();
}
createIntrospector(db) {
return new kysely.SqliteIntrospector(db);
}
};
var ConnectionMutex = class {
promise;
resolve;
async lock() {
while (this.promise) {
await this.promise;
}
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
}
unlock() {
const resolve = this.resolve;
this.promise = void 0;
this.resolve = void 0;
resolve?.();
}
};
async function runSavepoint(command, createQueryId, connection, savepointName, compileQuery) {
await connection.executeQuery(
compileQuery(
kysely.RawNode.createWithChildren([
kysely.RawNode.createWithSql(`${command} `),
kysely.IdentifierNode.create(savepointName)
// ensures savepointName gets sanitized
]),
createQueryId()
)
);
}
var BaseSqliteDriver = class {
mutex = new ConnectionMutex();
conn;
savepoint;
releaseSavepoint;
rollbackToSavepoint;
init;
/**
* Base abstract class that implements {@link Driver}
*
* You **MUST** assign `this.conn` in `init` and implement `destroy` method
*/
constructor(init) {
this.init = () => import('kysely').then(({ createQueryId }) => {
if (createQueryId) {
this.savepoint = runSavepoint.bind(null, "savepoint", createQueryId);
this.releaseSavepoint = runSavepoint.bind(null, "release", createQueryId);
this.rollbackToSavepoint = runSavepoint.bind(null, "rollback to", createQueryId);
}
}).then(init);
}
async acquireConnection() {
await this.mutex.lock();
return this.conn;
}
async beginTransaction(connection) {
await connection.executeQuery(kysely.CompiledQuery.raw("begin"));
}
async commitTransaction(connection) {
await connection.executeQuery(kysely.CompiledQuery.raw("commit"));
}
async rollbackTransaction(connection) {
await connection.executeQuery(kysely.CompiledQuery.raw("rollback"));
}
async releaseConnection() {
this.mutex.unlock();
}
};
function buildQueryFnAlt(exec) {
return async (isSelect, sql, parameters) => isSelect ? { rows: await exec.all(sql, parameters) } : { rows: [], ...await exec.run(sql, parameters) };
}
function buildQueryFn(exec) {
return async (isSelect, sql, parameters) => {
const rows = await exec.all(sql, parameters);
return isSelect || rows.length ? { rows } : { rows: [], ...await exec.run("select 1") };
};
}
function parseBigInt(num) {
return num === void 0 || num === null ? void 0 : BigInt(num);
}
var GenericSqliteDriver = class extends BaseSqliteDriver {
db;
constructor(executor, onCreateConnection) {
super(async () => {
this.db = await executor();
this.conn = new GenericSqliteConnection(this.db);
await onCreateConnection?.(this.conn);
});
}
async destroy() {
await this.db?.close();
}
};
var GenericSqliteConnection = class {
constructor(db) {
this.db = db;
}
async *streamQuery({ parameters, query, sql }) {
if (!this.db.iterator) {
throw new Error("streamQuery() is not supported.");
}
const it = this.db.iterator(kysely.SelectQueryNode.is(query), sql, parameters);
for await (const row of it) {
yield { rows: [row] };
}
}
async executeQuery({ parameters, query, sql }) {
return await this.db.query(kysely.SelectQueryNode.is(query), sql, parameters);
}
};
// src/dialect.ts
var GenericSqliteDialect = class extends BaseSqliteDialect {
/**
* Dialect for generic SQLite that run SQLs in current thread
*
* @param executor function to create {@link IGenericSqlite}
* @param onCreateConnection optional callback after connection created
*/
constructor(executor, onCreateConnection) {
super(() => new GenericSqliteDriver(executor, onCreateConnection));
}
};
exports.BaseSqliteDialect = BaseSqliteDialect;
exports.BaseSqliteDriver = BaseSqliteDriver;
exports.GenericSqliteConnection = GenericSqliteConnection;
exports.GenericSqliteDialect = GenericSqliteDialect;
exports.GenericSqliteDriver = GenericSqliteDriver;
exports.buildQueryFn = buildQueryFn;
exports.buildQueryFnAlt = buildQueryFnAlt;
exports.parseBigInt = parseBigInt;