/** * # 函数 数据库迁移执行器 * 读取 src/db/migrations/*.sql 按文件名顺序应用,记录到 drizzle.__migrations。 * 支持重复执行(幂等)。Bun.sql 直连,不依赖 pg/postgres.js。 */ import { readdirSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { SQL } from "bun"; const url = process.env.DATABASE_URL || "postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot"; const sql = new SQL(url); await sql`CREATE SCHEMA IF NOT EXISTS drizzle`; await sql`CREATE TABLE IF NOT EXISTS drizzle.__migrations (id serial primary key, hash text unique, created_at timestamptz default now())`; const applied = new Set(); for (const row of await sql`SELECT hash FROM drizzle.__migrations`.values()) applied.add(row[0] as string); const dir = join(import.meta.dir, "../src/db/migrations"); const files = readdirSync(dir).filter((f) => f.endsWith(".sql")).sort(); let ran = 0; for (const f of files) { if (applied.has(f)) continue; const content = readFileSync(join(dir, f), "utf8"); await sql.begin(async (tx) => { await tx.unsafe(content); await tx`INSERT INTO drizzle.__migrations (hash) VALUES (${f})`; }); console.log(`applied ${f}`); ran++; } console.log(ran === 0 ? "already up to date" : `done: ${ran} migration(s)`); sql.end();