Something went wrong. Try again.
Japanese learning that pulls JA Bluesky posts, scores them per-token, and serves them thricely.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// One-shot migration runner. CRDB DDL is async; apply each statement// on a pinned connection and retry transient "column does not exist"// errors that fire when an index references a column whose ADD hasn't// fully propagated.
import { readFileSync } from "node:fs"import { Pool } from "pg"
const path = process.argv[2]if (!path) { console.error("usage: apply-migration <path>") process.exit(1)}
const url = process.env.COCKROACH_URLif (!url) { console.error("COCKROACH_URL is required") process.exit(1)}
const sql = readFileSync(path, "utf8")const stmts = sql .split(/;\s*\n/) .map((seg) => // Strip full-line SQL comments (-- …) so a statement that starts // with a comment block still gets kept. seg .split("\n") .filter((line) => !line.trim().startsWith("--")) .join("\n") .trim() ) .filter((s) => s.length > 0)
const pool = new Pool({ connectionString: url })const client = await pool.connect()try { for (const s of stmts) { const head = s.split("\n")[0]!.slice(0, 80) let attempt = 0 while (true) { try { await client.query(s) console.log("✓", head) break } catch (err) { const msg = err instanceof Error ? err.message : String(err) if (attempt < 5 && /column .* does not exist/.test(msg)) { attempt++ await new Promise((r) => setTimeout(r, 500 * attempt)) continue } console.error("✗", head, msg) throw err } } }} finally { client.release() await pool.end()}