Files
bun-mariadb/dist/commands/import.js
T
2026-07-30 07:19:07 +01:00

95 lines
4.6 KiB
JavaScript

import { Command } from "commander";
import path from "path";
import fs from "fs";
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import grabDBDir from "../utils/grab-db-dir";
import grabSortedExports from "../utils/grab-sorted-exports";
import grabBackupData from "../utils/grab-backup-data";
import { restoreDatabase } from "../utils/mariadb-dump-restore";
import { isArchivePath, isSqlPath, readExportArchive, } from "../utils/export-archive";
import { resolveDataFile } from "../utils/resolve-and-load-data-file";
import { AppData } from "../data/app-data";
function formatChoice(name, index) {
const { backup_date } = grabBackupData({ backup_name: name });
const time = Number.isNaN(backup_date.getTime())
? "unknown date"
: `${backup_date.toDateString()} ${backup_date.getHours()}:${backup_date.getMinutes()}:${backup_date.getSeconds().toString().padStart(2, "0")}`;
return `#${index + 1}: ${name} (${time})`;
}
export default function () {
return new Command("import")
.description("Import an SQL dump, or a full export archive (SQL + schema)")
.argument("[file]", "Path to .sql file or export archive (.tar.gz / .tar / .zip)")
.option("--sql-only", "When importing an archive, restore SQL only (skip writing schema)")
.option("--schema-only", "When importing an archive, write schema only (skip SQL restore)")
.action(async (fileArg, opts) => {
console.log(`Importing database ...`);
const config = global.CONFIG;
const { db_dir, export_dir } = grabDBDir({ config });
try {
let filePath = fileArg ? path.resolve(fileArg) : "";
if (!filePath) {
const candidates = grabSortedExports({ config }).filter((b) => isArchivePath(b));
if (!candidates[0]) {
console.error(`No export archives found in \`${export_dir}\`. Use \`export\`, or pass a file path.`);
process.exit(1);
}
const selected = await select({
message: "Select an export to import:",
choices: candidates.map((b, i) => ({
name: formatChoice(b, i),
value: b,
})),
});
filePath = path.join(export_dir, selected);
}
if (!fs.existsSync(filePath)) {
console.error(chalk.red(`File not found: ${filePath}`));
process.exit(1);
}
if (isSqlPath(filePath)) {
if (opts.schemaOnly) {
console.error(chalk.red(`--schema-only requires an export archive, not a plain .sql file.`));
process.exit(1);
}
const sql = fs.readFileSync(filePath, "utf-8");
await restoreDatabase(config, sql);
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))}${filePath}`);
process.exit(0);
}
if (!isArchivePath(filePath)) {
console.error(chalk.red(`Unsupported file type: ${filePath}. Use .sql, .tar.gz, .tar, or .zip.`));
process.exit(1);
}
if (opts.sqlOnly && opts.schemaOnly) {
console.error(chalk.red(`Cannot combine --sql-only and --schema-only.`));
process.exit(1);
}
const { sql, schema, schemaFileName } = await readExportArchive(filePath);
if (!opts.schemaOnly) {
await restoreDatabase(config, sql);
console.log(chalk.green(`SQL restored from archive`));
}
if (!opts.sqlOnly) {
const existing = resolveDataFile(db_dir, AppData.DbSchemaFileName);
const schemaPath = path.join(db_dir, schemaFileName);
// Remove a differently-named schema so only one format remains
if (existing &&
path.resolve(existing.path) !== path.resolve(schemaPath)) {
fs.unlinkSync(existing.path);
console.log(chalk.dim(`Removed previous schema file: ${existing.basename}`));
}
fs.writeFileSync(schemaPath, schema, "utf-8");
console.log(chalk.green(`Schema written → ${schemaPath}`));
}
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))}${filePath}`);
process.exit(0);
}
catch (error) {
console.error(chalk.red(`Import ERROR => ${error.message}`));
process.exit(1);
}
});
}