Created
September 1, 2023 16:34
-
-
Save mizchi/951e0cc4d31d77affc894b4a8557cb2c to your computer and use it in GitHub Desktop.
Create kysely client on qwik dev
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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