feat(db): Bun.SQL Kysely dialect for sqlite and postgres
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6c5a9fbad9
commit
8248a2ac27
@@ -0,0 +1,63 @@
|
||||
import { SQL } from "bun";
|
||||
import { afterAll, afterEach, beforeEach, describe } from "bun:test";
|
||||
import { createDb, type Db } from "./db.ts";
|
||||
import type { Dialect } from "./dialect.ts";
|
||||
import { migrateToLatest } from "./migrate.ts";
|
||||
|
||||
/**
|
||||
* Register `describe("<name> [<dialect>]")` for SQLite, and for Postgres when
|
||||
* `TEST_POSTGRES_URL` is set. Every test gets a fresh, migrated database:
|
||||
* SQLite `:memory:`, or a new `st_<random>` database on the Postgres server.
|
||||
*/
|
||||
export function forEachDialect(name: string, fn: (getDb: () => Db) => void): void {
|
||||
const dialects: Dialect[] = ["sqlite"];
|
||||
const pgUrl = process.env.TEST_POSTGRES_URL;
|
||||
if (pgUrl) dialects.push("postgres");
|
||||
|
||||
for (const dialect of dialects) {
|
||||
describe(`${name} [${dialect}]`, () => {
|
||||
let current: Db | undefined;
|
||||
const created: string[] = [];
|
||||
|
||||
beforeEach(async () => {
|
||||
let url = "sqlite://:memory:";
|
||||
if (dialect === "postgres") {
|
||||
const dbName = `st_${crypto.randomUUID().replaceAll("-", "")}`;
|
||||
await withAdmin(pgUrl!, (admin) => admin.unsafe(`create database "${dbName}"`));
|
||||
created.push(dbName);
|
||||
const u = new URL(pgUrl!);
|
||||
u.pathname = `/${dbName}`;
|
||||
url = u.toString();
|
||||
}
|
||||
current = await createDb(url);
|
||||
await migrateToLatest(current);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await current?.close();
|
||||
current = undefined;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
if (created.length === 0) return;
|
||||
await withAdmin(pgUrl!, async (admin) => {
|
||||
for (const dbName of created) await admin.unsafe(`drop database if exists "${dbName}" with (force)`);
|
||||
});
|
||||
});
|
||||
|
||||
fn(() => {
|
||||
if (!current) throw new Error("getDb() called outside a test");
|
||||
return current;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function withAdmin<T>(url: string, f: (admin: SQL) => Promise<T>): Promise<T> {
|
||||
const admin = new SQL(url);
|
||||
try {
|
||||
return await f(admin);
|
||||
} finally {
|
||||
await admin.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user