UNPKG

sqlocal

Version:

SQLocal makes it easy to run SQLite3 in the browser, backed by the origin private file system.

99 lines (83 loc) 2.79 kB
import { CompiledQuery, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, } from 'kysely'; import type { DatabaseConnection, Dialect, Driver, QueryResult } from 'kysely'; import { SQLocal } from '../index.js'; import type { Transaction } from '../types.js'; import { convertRowsToObjects } from '../lib/convert-rows-to-objects.js'; import { sqlTag } from '../lib/sql-tag.js'; /** * A subclass of the `SQLocal` client that provides an additional property * for using SQLocal as a dialect for the Kysely query builder. * @see {@link https://sqlocal.dev/kysely/setup} */ export class SQLocalKysely extends SQLocal { /** * A Kysely dialect that implements the interface needed for * Kysely to interact with databases through SQLocal. * @see {@link https://sqlocal.dev/kysely/setup} */ dialect: Dialect = { createAdapter: () => new SqliteAdapter(), createDriver: () => new SQLocalKyselyDriver(this), createIntrospector: (db) => new SqliteIntrospector(db), createQueryCompiler: () => new SqliteQueryCompiler(), }; } class SQLocalKyselyDriver implements Driver { constructor(private client: SQLocalKysely) {} async init(): Promise<void> {} async acquireConnection(): Promise<SQLocalKyselyConnection> { return new SQLocalKyselyConnection(this.client); } async releaseConnection(): Promise<void> {} async beginTransaction(connection: SQLocalKyselyConnection): Promise<void> { connection.transaction = await this.client.beginTransaction(); } async commitTransaction(connection: SQLocalKyselyConnection): Promise<void> { await connection.transaction?.commit(); connection.transaction = null; } async rollbackTransaction( connection: SQLocalKyselyConnection ): Promise<void> { await connection.transaction?.rollback(); connection.transaction = null; } async destroy(): Promise<void> { await this.client.destroy(); } } class SQLocalKyselyConnection implements DatabaseConnection { transaction: Transaction | null = null; constructor(private client: SQLocalKysely) {} async executeQuery<Result>( query: CompiledQuery ): Promise<QueryResult<Result>> { let rows; let affectedRows: bigint | undefined; if (this.transaction === null) { const statement = sqlTag(query.sql, query.parameters); const result = await this.client.exec( statement.sql, statement.params, 'all' ); rows = convertRowsToObjects(result.rows, result.columns); affectedRows = result.numAffectedRows; } else { rows = await this.transaction.query(query); affectedRows = this.transaction.lastAffectedRows; } return { rows: rows as Result[], numAffectedRows: affectedRows, }; } async *streamQuery(): AsyncGenerator<never, void, unknown> { throw new Error('SQLite3 does not support streaming.'); } }