v3: added comment likes, added votes/likes list view, added db migrations mechanism, updated project dependencies
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 42s
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 42s
This commit is contained in:
43
api/sql/migrate.ts
Normal file
43
api/sql/migrate.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { DatabaseSync } from "node:sqlite";
|
||||
import { up as up0001CommentLikes } from "./migrations/0001_comment_likes.ts";
|
||||
|
||||
interface Migration {
|
||||
name: string;
|
||||
up: (db: DatabaseSync) => void;
|
||||
}
|
||||
|
||||
// Append-only — never edit or reorder a migration once it has shipped.
|
||||
// Each `up` must be idempotent: it also runs against fresh databases created
|
||||
// straight from schema.sql, where the change it makes already exists.
|
||||
const MIGRATIONS: Migration[] = [
|
||||
{ name: "0001_comment_likes", up: up0001CommentLikes },
|
||||
];
|
||||
|
||||
export function runMigrations(db: DatabaseSync): void {
|
||||
db.exec(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
name TEXT PRIMARY KEY,
|
||||
applied_at TEXT NOT NULL
|
||||
);`);
|
||||
|
||||
const applied = new Set(
|
||||
(db.prepare(`SELECT name FROM schema_migrations;`).all() as {
|
||||
name: string;
|
||||
}[]).map((r) => r.name),
|
||||
);
|
||||
|
||||
for (const { name, up } of MIGRATIONS) {
|
||||
if (applied.has(name)) continue;
|
||||
db.exec("BEGIN;");
|
||||
try {
|
||||
up(db);
|
||||
db.prepare(
|
||||
`INSERT INTO schema_migrations (name, applied_at) VALUES (?, ?);`,
|
||||
).run(name, new Date().toISOString());
|
||||
db.exec("COMMIT;");
|
||||
console.log(`[migrate] applied ${name}`);
|
||||
} catch (err) {
|
||||
db.exec("ROLLBACK;");
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user