WebArena-ShopSmart / scripts /bootstrap-db.mjs
Jack
Fixed login with seeded accounts
dcbdcef
import { readFile } from "node:fs/promises";
import mysql from "mysql2/promise";
const DATABASE_URL = process.env.DATABASE_URL;
const BOOTSTRAP_SQL_PATH = new URL("../db/init/00-bootstrap.sql", import.meta.url);
const RETRY_DELAY_MS = 2000;
const MAX_ATTEMPTS = 30;
if (!DATABASE_URL) {
console.error("DATABASE_URL is required to bootstrap the database.");
process.exit(1);
}
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function connectWithRetry() {
let lastError;
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
try {
const connection = await mysql.createConnection({
uri: DATABASE_URL,
multipleStatements: true,
});
await connection.query("SELECT 1");
return connection;
} catch (error) {
lastError = error;
console.log(
`Database connection attempt ${attempt}/${MAX_ATTEMPTS} failed. Retrying in ${RETRY_DELAY_MS}ms.`
);
await sleep(RETRY_DELAY_MS);
}
}
throw lastError;
}
async function tableExists(connection, tableName) {
const [rows] = await connection.query("SHOW TABLES LIKE ?", [tableName]);
return Array.isArray(rows) && rows.length > 0;
}
function stripUseStatement(sql) {
return sql.replace(/^\s*USE\s+[^;]+;\s*/i, "");
}
async function bootstrapIfNeeded() {
const connection = await connectWithRetry();
try {
const hasUsers = await tableExists(connection, "users");
const hasSessions = await tableExists(connection, "sessions");
const hasStores = await tableExists(connection, "stores");
if (hasUsers && hasSessions && hasStores) {
console.log("Database bootstrap skipped because required tables already exist.");
return;
}
const sql = await readFile(BOOTSTRAP_SQL_PATH, "utf8");
await connection.query(stripUseStatement(sql));
console.log("Database bootstrap completed from db/init/00-bootstrap.sql.");
} finally {
await connection.end();
}
}
bootstrapIfNeeded().catch((error) => {
console.error("Database bootstrap failed.", error);
process.exit(1);
});