SPB Git
1.3 KB · 24 lines typescript
1import "./_env";2import postgres from "postgres";3import { readdirSync, readFileSync } from "node:fs";4import { join } from "node:path";5import { createHash } from "node:crypto";67const url = process.env.DATABASE_URL_ADMIN ?? process.env.DATABASE_URL;8if (!url) { console.error("DATABASE_URL missing"); process.exit(1); }9const sql = postgres(url, { max: 1, onnotice: () => {} });10const dir = join(import.meta.dirname, "..", "drizzle");11const files = readdirSync(dir).filter((f) => /^\d{4}_.*\.sql$/.test(f)).sort();12await sql`CREATE TABLE IF NOT EXISTS schema_migrations (name text PRIMARY KEY, checksum text NOT NULL, applied_at timestamptz NOT NULL DEFAULT now())`;13const applied = new Map((await sql`SELECT name, checksum FROM schema_migrations`).map((r) => [r.name as string, r.checksum as string]));14let n = 0;15for (const f of files) {16  const body = readFileSync(join(dir, f), "utf8"); const sum = createHash("sha256").update(body).digest("hex");17  if (applied.has(f)) { if (applied.get(f) !== sum) console.warn(`! ${f} changed after being applied (checksum mismatch)`); continue; }18  console.log(`→ applying ${f}`);19  await sql.begin(async (tx) => { await tx.unsafe(body); await tx`INSERT INTO schema_migrations (name, checksum) VALUES (${f}, ${sum})`; });20  n++;21}22console.log(n ? `${n} migration(s) applied` : "schema up to date");23await sql.end();24
Files · main
Menu

Theme