UNPKG

copybase

Version:

Copy or backup databases quickly

179 lines (175 loc) 6.99 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadConfig = loadConfig; exports.backup = backup; exports.restore = restore; exports.copy = copy; exports.listTables = listTables; const os_1 = __importDefault(require("os")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const cosmiconfig_1 = require("cosmiconfig"); const dayjs_1 = __importDefault(require("dayjs")); const providers_1 = __importDefault(require("./providers")); const util_1 = require("./util"); /** * check databaseName exists in the provided copybase configuration * * @param databaseName * @param config * @returns */ function checkDatabaseConfig(databaseName, config) { const dbConfig = config.databases[databaseName]; const databaseNames = Object.keys(config.databases); const supportedDbTypes = Object.keys(providers_1.default); if (!dbConfig) { console.error(`Invalid database source: "${databaseName}". Must be ${databaseNames.join(", ")}`); return false; } if (!providers_1.default[dbConfig.protocol]) { console.error(`Invalid database protocol: ${dbConfig.protocol}. Must be [${supportedDbTypes.join(", ")}]`); return false; } return true; } /** * Load copybase configuration * * @param moduleName * @returns */ function loadConfig(moduleName) { const explorerSync = (0, cosmiconfig_1.cosmiconfigSync)(moduleName); const config = explorerSync.search(); if (!config) { return null; } const databases = config.config.databases; Object.entries(config.config.databases).map(([key, dbConfig]) => { config.config.databases[key] = Object.assign(Object.assign({}, (dbConfig.uri ? (0, util_1.parseDatabaseUri)(dbConfig.uri) : {})), dbConfig); }); return { currentDir: process.cwd(), databases, backup: Object.assign({ filenamePattern: "YYYYMMDDTHHmmss" }, config === null || config === void 0 ? void 0 : config.config.backup), }; } /** * backup a database into a given folder * @param config * @param param1 * @param options * @returns */ function backup(config_1, _a, options_1) { return __awaiter(this, arguments, void 0, function* (config, { database }, options) { var _b; const { verbose } = options || {}; if (!checkDatabaseConfig(database, config)) { return; } if (!((_b = config === null || config === void 0 ? void 0 : config.backup) === null || _b === void 0 ? void 0 : _b.folder)) { console.info("Please provide a backupFolder value in config"); return; } console.info(`Backup ${database} into ${config.backup.folder}`); const dbConfig = config.databases[database]; const provider = new providers_1.default[dbConfig.protocol](Object.assign(Object.assign({}, dbConfig), { verbose })); const outputFile = path_1.default.join(config.backup.folder, database, `${(0, dayjs_1.default)().format(config.backup.filenamePattern)}`); yield fs_1.default.promises.mkdir(path_1.default.dirname(outputFile), { recursive: true }); yield provider.dump(outputFile); }); } /** * Restore a database from a given folder * @param config * @param param1 * @param options * @returns */ function restore(config_1, _a, options_1) { return __awaiter(this, arguments, void 0, function* (config, { from, toDatabase }, options) { const { verbose } = options || {}; if (!checkDatabaseConfig(toDatabase, config)) { return; } const dbConfig = config.databases[toDatabase]; const provider = new providers_1.default[dbConfig.protocol](Object.assign(Object.assign({}, dbConfig), { verbose })); const filePath = [ from, path_1.default.join(config.backup.folder, from), path_1.default.join(process.cwd(), from), ].find((filePath) => fs_1.default.existsSync(filePath)); if (!filePath) { console.error(`Folder "${from}" not found`); return; } yield provider.restore(from); }); } /** * Copy a database to another database * * @param config * @param param1 * @param options * @returns */ function copy(config_1, _a, options_1) { return __awaiter(this, arguments, void 0, function* (config, { fromDatabase, toDatabase }, options) { const { verbose } = options || {}; if (!checkDatabaseConfig(fromDatabase, config)) { return; } if (!checkDatabaseConfig(toDatabase, config)) { return; } const fromConfig = config.databases[fromDatabase]; const toConfig = config.databases[toDatabase]; if (fromConfig.protocol !== fromConfig.protocol) { console.error(`Incompatible database protocol: ${fromConfig.protocol} !== ${toConfig.protocol}`); return; } const from = new providers_1.default[fromConfig.protocol](Object.assign(Object.assign({}, fromConfig), { verbose })); const to = new providers_1.default[toConfig.protocol](Object.assign(Object.assign({}, toConfig), { verbose })); console.info(`Copy ${fromDatabase} to ${toDatabase}`); const outputFile = path_1.default.join(os_1.default.tmpdir(), fromDatabase); const exitCode = yield from.dump(outputFile); if (exitCode !== 0) { return; } yield to.restore(outputFile); }); } /** * List all tables from a given database * @param config * @param param1 * @param options * @returns */ function listTables(config_1, _a, options_1) { return __awaiter(this, arguments, void 0, function* (config, { database }, options) { const { verbose } = options || {}; if (!checkDatabaseConfig(database, config)) { return; } console.info(`List tables on ${database}`); const dbConfig = config.databases[database]; const provider = new providers_1.default[dbConfig.protocol](Object.assign(Object.assign({}, dbConfig), { verbose })); yield provider.listTables(); }); }