copybase
Version:
Copy or backup databases quickly
148 lines (145 loc) • 5.91 kB
JavaScript
;
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.listTables = exports.copy = exports.backup = exports.loadConfig = void 0;
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
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),
};
}
exports.loadConfig = loadConfig;
/**
* backup a database into a given folder
* @param config
* @param param1
* @param options
* @returns
*/
function backup(config, { database }, { verbose }) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (!checkDatabaseConfig(database, config)) {
return;
}
if (!((_a = config === null || config === void 0 ? void 0 : config.backup) === null || _a === void 0 ? void 0 : _a.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 promises_1.default.mkdir(path_1.default.dirname(outputFile), { recursive: true });
yield provider.dump(outputFile);
});
}
exports.backup = backup;
/**
* Copy a database to another database
*
* @param config
* @param param1
* @param options
* @returns
*/
function copy(config, { fromDatabase, toDatabase }, { verbose }) {
return __awaiter(this, void 0, void 0, function* () {
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);
});
}
exports.copy = copy;
/**
* List all tables from a given database
* @param config
* @param param1
* @param options
* @returns
*/
function listTables(config, { database }, { verbose }) {
return __awaiter(this, void 0, void 0, function* () {
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();
});
}
exports.listTables = listTables;