UNPKG

kysely-planetscale

Version:

Kysely dialect for PlanetScale Serverless

124 lines (123 loc) 4 kB
// src/index.ts import { Client, cast } from "@planetscale/database"; import { parseJSON } from "date-fns"; import { MysqlAdapter, MysqlIntrospector, MysqlQueryCompiler } from "kysely"; var PlanetScaleDialect = class { #config; constructor(config) { this.#config = config; } createAdapter() { return new MysqlAdapter(); } createDriver() { return new PlanetScaleDriver(this.#config); } createQueryCompiler() { return new MysqlQueryCompiler(); } createIntrospector(db) { return new MysqlIntrospector(db); } }; var PlanetScaleDriver = class { #client; constructor(config) { this.#client = new Client({ cast: inflateDates, ...config }); } async init() { } async acquireConnection() { return new PlanetScaleConnection(this.#client); } async beginTransaction(conn, settings) { return await conn.beginTransaction(settings); } async commitTransaction(conn) { return await conn.commitTransaction(); } async rollbackTransaction(conn) { return await conn.rollbackTransaction(); } async releaseConnection(_conn) { } async destroy() { } }; var sharedConnections = /* @__PURE__ */ new WeakMap(); var PlanetScaleConnection = class { #client; #transactionConn; #useSharedConnection; get #config() { return this.#client.config; } constructor(client, useSharedConnection = false, isForTransaction = false) { this.#client = client; this.#useSharedConnection = useSharedConnection && !isForTransaction; if (this.#useSharedConnection) { sharedConnections.set(this.#config, sharedConnections.get(this.#config) ?? this.#client.connection()); } } async executeQuery(compiledQuery) { if (this.#transactionConn) return this.execute(compiledQuery, this.#transactionConn); return this.#useSharedConnection ? this.execute(compiledQuery, sharedConnections.get(this.#config) || this.#client) : this.execute(compiledQuery, this.#client); } async execute(compiledQuery, conn) { const parameters = this.#config.format ? compiledQuery.parameters : compiledQuery.parameters.map((param) => param instanceof Date ? formatDate(param) : param); const results = await conn.execute(compiledQuery.sql, parameters); if (results.error) { throw results.error; } const numAffectedRows = results.rowsAffected == null ? void 0 : BigInt(results.rowsAffected); return { insertId: results.insertId !== null && results.insertId.toString() !== "0" ? BigInt(results.insertId) : void 0, rows: results.rows, // @ts-ignore replaces `QueryResult.numUpdatedOrDeletedRows` in kysely > 0.22 // following https://github.com/koskimas/kysely/pull/188 numAffectedRows }; } async beginTransaction(settings) { this.#transactionConn = this.#transactionConn ?? this.#client.connection(); if (settings.isolationLevel) { await this.#transactionConn.execute(`SET TRANSACTION ISOLATION LEVEL ${settings.isolationLevel}`); } await this.#transactionConn.execute("BEGIN"); } async commitTransaction() { if (!this.#transactionConn) throw new Error("No transaction to commit"); try { await this.#transactionConn.execute("COMMIT"); } finally { this.#transactionConn = void 0; } } async rollbackTransaction() { if (!this.#transactionConn) throw new Error("No transaction to rollback"); try { await this.#transactionConn.execute("ROLLBACK"); } finally { this.#transactionConn = void 0; } } async *streamQuery(_compiledQuery, _chunkSize) { throw new Error("PlanetScale Serverless Driver does not support streaming"); } }; function inflateDates(field, value) { if (field.type === "DATETIME" && value) return parseJSON(value); if (field.type === "TIMESTAMP" && value) return parseJSON(value); return cast(field, value); } function formatDate(date) { return date.toISOString().replace(/[TZ]/g, " ").trim(); } export { PlanetScaleDialect, inflateDates };