Build, Test, and Push CFDM Docker Image / test (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / create-release (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been cancelled
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { readFileSync, readdirSync } from "node:fs";
|
|
import Database from "better-sqlite3";
|
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
import { schema } from "./schema.js";
|
|
|
|
export type Sqlite = Database.Database;
|
|
export type Db = ReturnType<typeof drizzle<typeof schema>>;
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
export function resolveDatabasePath(databaseUrl: string): string {
|
|
const url = databaseUrl.startsWith("sqlite:")
|
|
? databaseUrl.slice("sqlite:".length)
|
|
: databaseUrl;
|
|
return url;
|
|
}
|
|
|
|
export function createDb(databaseUrl: string): { db: Db; sqlite: Sqlite } {
|
|
const path = resolveDatabasePath(databaseUrl);
|
|
const sqlite = new Database(path);
|
|
sqlite.pragma("journal_mode = WAL");
|
|
sqlite.pragma("synchronous = NORMAL");
|
|
sqlite.pragma("foreign_keys = ON");
|
|
const db = drizzle(sqlite, { schema });
|
|
return { db, sqlite };
|
|
}
|
|
|
|
export function createMemoryDb(): { db: Db; sqlite: Sqlite } {
|
|
const sqlite = new Database(":memory:");
|
|
sqlite.pragma("foreign_keys = ON");
|
|
const db = drizzle(sqlite, { schema });
|
|
return { db, sqlite };
|
|
}
|
|
|
|
export function runMigrations(sqlite: Sqlite): void {
|
|
const migrationsDir = join(__dirname, "..", "migrations");
|
|
const files = readdirSync(migrationsDir)
|
|
.filter((f) => f.endsWith(".sql"))
|
|
.sort();
|
|
|
|
sqlite.exec(
|
|
`CREATE TABLE IF NOT EXISTS _migrations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL UNIQUE,
|
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
)`,
|
|
);
|
|
|
|
for (const file of files) {
|
|
const applied = sqlite
|
|
.prepare("SELECT 1 FROM _migrations WHERE name = ?")
|
|
.get(file);
|
|
if (applied) continue;
|
|
|
|
const sql = readFileSync(join(migrationsDir, file), "utf-8");
|
|
sqlite.exec(sql);
|
|
sqlite.prepare("INSERT INTO _migrations (name) VALUES (?)").run(file);
|
|
}
|
|
}
|
|
|
|
export function healthCheck(sqlite: Sqlite): void {
|
|
sqlite.prepare("SELECT 1").get();
|
|
}
|