feat: ship self-hosted KOC LOOP workflows
This commit is contained in:
63
scripts/migrate-mysql.mjs
Normal file
63
scripts/migrate-mysql.mjs
Normal file
@@ -0,0 +1,63 @@
|
||||
import { readFile, readdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import mysql from "mysql2/promise";
|
||||
|
||||
function databaseUrl() {
|
||||
if (process.env.DATABASE_URL) return process.env.DATABASE_URL;
|
||||
const host = process.env.MYSQL_HOST ?? "127.0.0.1";
|
||||
const port = process.env.MYSQL_PORT ?? "3306";
|
||||
const user = encodeURIComponent(process.env.MYSQL_USER ?? "koc");
|
||||
const password = encodeURIComponent(process.env.MYSQL_PASSWORD ?? "");
|
||||
const database = process.env.MYSQL_DATABASE ?? "koc_loop";
|
||||
return `mysql://${user}:${password}@${host}:${port}/${database}`;
|
||||
}
|
||||
|
||||
const pool = mysql.createPool({
|
||||
uri: databaseUrl(),
|
||||
connectionLimit: 2,
|
||||
charset: "utf8mb4",
|
||||
timezone: "Z",
|
||||
});
|
||||
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [lockRows] = await connection.query(
|
||||
"SELECT GET_LOCK('koc-loop-schema-migration', 60) AS acquired",
|
||||
);
|
||||
if (Number(lockRows[0]?.acquired ?? 0) !== 1) {
|
||||
throw new Error("无法获取数据库迁移锁");
|
||||
}
|
||||
await connection.query(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version VARCHAR(255) PRIMARY KEY,
|
||||
applied_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci`);
|
||||
|
||||
const migrationDir = path.join(process.cwd(), "mysql");
|
||||
const files = (await readdir(migrationDir))
|
||||
.filter((file) => file.endsWith(".sql"))
|
||||
.sort();
|
||||
for (const file of files) {
|
||||
const [rows] = await connection.query(
|
||||
"SELECT version FROM schema_migrations WHERE version = ?",
|
||||
[file],
|
||||
);
|
||||
if (rows.length > 0) continue;
|
||||
const source = await readFile(path.join(migrationDir, file), "utf8");
|
||||
const statements = source
|
||||
.split(/^-- statement-breakpoint\s*$/m)
|
||||
.map((statement) => statement.trim())
|
||||
.filter(Boolean);
|
||||
for (const statement of statements) {
|
||||
await connection.query(statement);
|
||||
}
|
||||
await connection.query(
|
||||
"INSERT INTO schema_migrations (version) VALUES (?)",
|
||||
[file],
|
||||
);
|
||||
console.info(`applied ${file}`);
|
||||
}
|
||||
await connection.query("SELECT RELEASE_LOCK('koc-loop-schema-migration')");
|
||||
} finally {
|
||||
connection.release();
|
||||
await pool.end();
|
||||
}
|
||||
Reference in New Issue
Block a user