Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created September 1, 2023 16:34
Show Gist options
  • Save mizchi/951e0cc4d31d77affc894b4a8557cb2c to your computer and use it in GitHub Desktop.
Save mizchi/951e0cc4d31d77affc894b4a8557cb2c to your computer and use it in GitHub Desktop.
Create kysely client on qwik dev
import {
CompiledQuery,
DatabaseConnection,
DatabaseIntrospector,
Dialect,
Driver,
Kysely,
SqliteAdapter,
SqliteIntrospector,
SqliteQueryCompiler,
QueryCompiler,
QueryResult,
} from "kysely";
// generated by prisma-kysely
import type { DB } from "./db/types";
import { D1Database } from "@cloudflare/workers-types";
interface D1DialectConfig {
database: D1Database;
}
let _db: Kysely<DB> | undefined = undefined;
export const createDb = async (d1db: D1Database | undefined) => {
if (_db) return _db;
// production
if (d1db) {
return (_db = new Kysely<DB>({
dialect: new D1Dialect({ database: d1db }),
}));
}
// development
if (import.meta.env.DEV) {
const { D1DatabaseAPI, D1Database } = await import("@miniflare/d1");
const { createSQLiteDB } = await import("@miniflare/shared");
const db = await createSQLiteDB(
".wrangler/state/v3/d1/12cc3c45-e725-4b03-b38f-82dc744d102f/db.sqlite",
);
const d1db = new D1Database(new D1DatabaseAPI(db));
return (_db = new Kysely<DB>({
dialect: new D1Dialect({ database: d1db as any }),
}));
}
};
// --------- from kysely-d1 ------------
/**
* D1 dialect that adds support for [Cloudflare D1][0] in [Kysely][1].
* The constructor takes the instance of your D1 database that you bound in `wrangler.toml`.
*
* ```typescript
* new D1Dialect({
* database: env.DB,
* })
* ```
*
* [0]: https://blog.cloudflare.com/introducing-d1/
* [1]: https://github.com/koskimas/kysely
*/
export class D1Dialect implements Dialect {
#config: D1DialectConfig;
constructor(config: D1DialectConfig) {
this.#config = config;
}
createAdapter() {
return new SqliteAdapter();
}
createDriver(): Driver {
return new D1Driver(this.#config);
}
createQueryCompiler(): QueryCompiler {
return new SqliteQueryCompiler();
}
createIntrospector(db: Kysely<any>): DatabaseIntrospector {
return new SqliteIntrospector(db);
}
}
class D1Driver implements Driver {
#config: D1DialectConfig;
constructor(config: D1DialectConfig) {
this.#config = config;
}
async init(): Promise<void> {}
async acquireConnection(): Promise<DatabaseConnection> {
return new D1Connection(this.#config);
}
async beginTransaction(conn: D1Connection): Promise<void> {
return await conn.beginTransaction();
}
async commitTransaction(conn: D1Connection): Promise<void> {
return await conn.commitTransaction();
}
async rollbackTransaction(conn: D1Connection): Promise<void> {
return await conn.rollbackTransaction();
}
async releaseConnection(_conn: D1Connection): Promise<void> {}
async destroy(): Promise<void> {}
}
class D1Connection implements DatabaseConnection {
#config: D1DialectConfig;
// #transactionClient?: D1Connection
constructor(config: D1DialectConfig) {
this.#config = config;
}
async executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>> {
// Transactions are not supported yet.
// if (this.#transactionClient) return this.#transactionClient.executeQuery(compiledQuery)
const results = await this.#config.database
.prepare(compiledQuery.sql)
.bind(...compiledQuery.parameters)
.all();
if (results.error) {
throw new Error(results.error);
}
const numAffectedRows =
results.meta.changes > 0 ? BigInt(results.meta.changes) : undefined;
return {
insertId:
results.meta.last_row_id === undefined ||
results.meta.last_row_id === null
? undefined
: BigInt(results.meta.last_row_id),
rows: (results?.results as O[]) || [],
numAffectedRows,
// @ts-ignore deprecated in kysely >= 0.23, keep for backward compatibility.
numUpdatedOrDeletedRows: numAffectedRows,
};
}
async beginTransaction() {
// this.#transactionClient = this.#transactionClient ?? new PlanetScaleConnection(this.#config)
// this.#transactionClient.#conn.execute('BEGIN')
throw new Error("Transactions are not supported yet.");
}
async commitTransaction() {
// if (!this.#transactionClient) throw new Error('No transaction to commit')
// this.#transactionClient.#conn.execute('COMMIT')
// this.#transactionClient = undefined
throw new Error("Transactions are not supported yet.");
}
async rollbackTransaction() {
// if (!this.#transactionClient) throw new Error('No transaction to rollback')
// this.#transactionClient.#conn.execute('ROLLBACK')
// this.#transactionClient = undefined
throw new Error("Transactions are not supported yet.");
}
async *streamQuery<O>(
_compiledQuery: CompiledQuery,
_chunkSize: number,
): AsyncIterableIterator<QueryResult<O>> {
throw new Error("D1 Driver does not support streaming");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment