v0.10.5 首页 H2 产品线入口 ×6:ImageBoxWidget 重构为 Elementor 忠实 DOM + slim 白名单补齐 + H2 scoped CSS(post-18 对齐,桌面/移动/hover 实测一致)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* # 函数 数据库迁移执行器
|
||||
* 读取 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<string>();
|
||||
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();
|
||||
Reference in New Issue
Block a user