"use strict"; /* * バックアップパイプライン全体(pg_dump→分割→アップロード→ローテーション→ログ)を * 本番DBに触れずに試せるよう、テスト用DBを作成・削除するヘルパー。 * PGHOST/PGPORT/PGUSER/PGPASSWORD は通常バックアップと同じ接続情報を再利用する。 */ const { spawn } = require("child_process"); function runCommand(bin, args, env) { return new Promise((resolve, reject) => { const child = spawn(bin, args, { env, stdio: ["ignore", "pipe", "pipe"] }); let stdout = ""; let stderr = ""; child.stdout.on("data", (d) => (stdout += d.toString("utf8"))); child.stderr.on("data", (d) => (stderr += d.toString("utf8"))); child.on("error", (err) => reject(new Error(`${bin} 起動失敗: ${err.message}`))); child.on("close", (code) => { if (code !== 0) { reject(new Error(`${bin} 異常終了 (code=${code}): ${(stderr || stdout).trim()}`)); return; } resolve({ stdout: stdout.trim(), stderr: stderr.trim() }); }); }); } function buildEnv() { const env = { ...process.env }; if (process.env.PGPASSWORD) { env.PGPASSWORD = process.env.PGPASSWORD; } return env; } function connectionInfo() { return { host: process.env.PGHOST || "localhost", port: process.env.PGPORT || "5432", user: process.env.PGUSER || "postgres", }; } async function createTestDb(dbName) { const bin = process.env.PG_CREATEDB_BIN || "createdb"; const { host, port, user } = connectionInfo(); console.log(`テスト用DB作成: ${dbName} (host=${host} port=${port} user=${user})`); try { await runCommand(bin, ["-h", host, "-p", String(port), "-U", user, dbName], buildEnv()); console.log(`テスト用DB作成完了: ${dbName}`); } catch (err) { console.error(`テスト用DB作成失敗: ${err.message}`); console.error(`既に存在する場合は先に 'node backup.js drop-test-db ${dbName}' を実行してください。`); throw err; } } async function dropTestDb(dbName) { const bin = process.env.PG_DROPDB_BIN || "dropdb"; const { host, port, user } = connectionInfo(); console.log(`テスト用DB削除: ${dbName} (host=${host} port=${port} user=${user})`); await runCommand(bin, ["-h", host, "-p", String(port), "-U", user, "--if-exists", dbName], buildEnv()); console.log(`テスト用DB削除完了: ${dbName}`); } // restore.js が使う汎用版(任意のDB名に対して作成・削除)。 // dropDatabase は既定で --if-exists を付けない(復元対象DBが本当に存在するか厳密に確認するため)。 async function createDatabase(dbName) { const bin = process.env.PG_CREATEDB_BIN || "createdb"; const { host, port, user } = connectionInfo(); await runCommand(bin, ["-h", host, "-p", String(port), "-U", user, dbName], buildEnv()); } async function dropDatabase(dbName, { ifExists = false } = {}) { const bin = process.env.PG_DROPDB_BIN || "dropdb"; const { host, port, user } = connectionInfo(); const args = ["-h", host, "-p", String(port), "-U", user]; if (ifExists) args.push("--if-exists"); args.push(dbName); await runCommand(bin, args, buildEnv()); } module.exports = { createTestDb, dropTestDb, createDatabase, dropDatabase };