ken_nogi/dbbackup/lib/testDb.js
Kenichiro NOGI 67cc3da6c8 up
2026-07-13 19:02:04 +09:00

92 lines
3.4 KiB
JavaScript

"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 };