import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; import url from "node:url"; import sqlite from "./sqlite.cjs"; import * as u from "./utils.mjs"; const DIRNAME = path.dirname(url.fileURLToPath(import.meta.url)); export const MIGRATIONS_DIR = DIRNAME + "/sql/migrations/"; export const runMigrations = async (logFn, db) => { assert(db); await db.exec(` BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS migrations ( filename TEXT NOT NULL PRIMARY KEY ); COMMIT TRANSACTION; `); const done = [...(await db.all("SELECT filename FROM migrations;"))] .map(row => row.filename); const allFiles = fs.readdirSync(MIGRATIONS_DIR, "UTF-8"); const pending = u.difference(new Set(allFiles), new Set(done)); const sortedPending = [...pending].sort(u.strSortFn); for (const filename of sortedPending) { logFn({ log: "exec-migration", filename }); const sql = fs.readFileSync(MIGRATIONS_DIR + filename, "UTF-8"); await db.exec("BEGIN TRANSACTION;"); await db.exec(sql); await db.run( "INSERT INTO migrations (filename) VALUES ($filename);", { $filename: filename }, ); await db.exec("COMMIT TRANSACTION;") } };