UNPKG

@riao/dbal

Version:
181 lines 8.22 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MigrationRunner = void 0; const fs = require("fs"); const path_1 = require("path"); const ts_import_ts_1 = require("ts-import-ts"); const _001_create_migration_table_1 = require("./migrations/001-create-migration-table"); const migration_package_1 = require("./migration-package"); const _002_add_migration_package_column_1 = require("./migrations/002-add-migration-package-column"); /** * Runs migrations */ class MigrationRunner { constructor(db) { this.db = db; } /** * Run migrations * @deprecated This method will change parameters in a future release. * Switch to runWithOptions() to prepare for this change. * * @param migrations (Optional) Folder to find migrations in. Default is * db.getMigraitonDirectory() * @param log (Optional) Log function. Defaults to console.log * @param direction (Optional) Run migrations up or down? * @param steps (Optional) Run a certain number of steps? */ run(migrations, /* eslint-disable-next-line no-console */ log = console.log, direction = 'up', steps) { return __awaiter(this, void 0, void 0, function* () { return yield this.runWithOptions({ migrations, log, direction, steps, }); }); } runWithOptions(options) { return __awaiter(this, void 0, void 0, function* () { const name = options.package || this.db.name || 'database'; let migrations = options.migrations || this.db.getMigrationsDirectory(); // eslint-disable-next-line no-console const optionsLog = options.log || console.log; const log = (...args) => { optionsLog(`[${name}]\t`, ...args); }; const direction = options.direction || 'up'; let steps = options.steps; const pkg = options.package || null; if (steps === -1) { steps = undefined; } if (steps !== undefined && steps < 0) { throw new Error('Steps must be a positive integer, or -1 for all.'); } // Create migration table, if not existing yield this.runRiaoDbalMigrations(); // Query migrations that have already run const repo = this.db.getQueryRepository(); const alreadyRanMigrations = yield repo.find({ columns: ['name'], table: 'riao_migration', where: { package: pkg ? pkg : null }, }); const alreadyRanNames = alreadyRanMigrations.map((migration) => migration.name); if (typeof migrations === 'string') { // Get migration files in folder migrations = this.loadMigrationsFromDirectory(migrations); } const migrationNames = Object.keys(migrations); if (!migrationNames.length) { log('No migrations found!'); return; } // Check which migrations need to run let migrationsToRun; if (direction === 'up') { migrationsToRun = migrationNames.filter((file) => !alreadyRanNames.includes(file)); } else { migrationsToRun = alreadyRanNames.reverse(); } if (!migrationsToRun.length) { log('All migrations have already run'); return; } log(`Discovered ${migrationsToRun.length} ` + 'pending migrations in this direction.'); if (steps !== undefined) { migrationsToRun = migrationsToRun.slice(0, steps); } log(`Running ${migrationsToRun.length} migrations...`); // Run each migration for (const name of migrationsToRun) { // Run the migration log(direction.toLocaleUpperCase() + ' | ', name); const migration = migrations[name]; if (migration instanceof migration_package_1.MigrationPackage) { log('Importing packaged migrations for ' + migration.name + '...'); const importedMigrationTypes = yield migration.getMigrations(); const PackagedMigrations = Object.keys(importedMigrationTypes).reduce((obj, key) => { const migrationType = importedMigrationTypes[key]; obj[key] = new migrationType(this.db); return obj; }, {}); yield this.runWithOptions(Object.assign(Object.assign({}, options), { steps: undefined, migrations: PackagedMigrations, package: migration.package })); continue; } yield migration[direction](); // Save the migration record if (direction === 'up') { yield repo.insert({ table: 'riao_migration', records: { name, package: pkg ? pkg : null }, }); } else { yield repo.delete({ table: 'riao_migration', where: { name, package: pkg ? pkg : null }, }); } } log('Rebuilding Schema...'); yield this.db.buildSchema(); log('Migrations Complete!'); }); } getMigrationName(filename) { return (0, path_1.basename)(filename.toLowerCase(), (0, path_1.extname)(filename)); } loadMigration(dir, filename) { const path = (0, path_1.join)(dir, filename); const migrationType = (0, ts_import_ts_1.tsimport)(path); const migration = new migrationType(this.db); return migration; } loadMigrationsFromDirectory(dir) { return fs .readdirSync(dir) .filter((filename) => /\.ts$/.test(filename)) .map((filename) => ({ name: this.getMigrationName(filename), migration: this.loadMigration(dir, filename), })) .reduce((obj, item) => { obj[item.name] = item.migration; return obj; }, {}); } runRiaoDbalMigrations() { return __awaiter(this, void 0, void 0, function* () { // Create table, if not existing const createMigrationTable = new _001_create_migration_table_1.CreateMigrationTable(this.db); yield createMigrationTable.up(); // Check if `package` column exists, and if not, add it const columns = yield this.db .getSchemaQueryRepository() .getColumns({ table: 'riao_migration' }); if (!columns.find((col) => col.name === 'package')) { const addMigrationPackageColumn = new _002_add_migration_package_column_1.AddMigrationPackageColumn(this.db); yield addMigrationPackageColumn.up(); } }); } } exports.MigrationRunner = MigrationRunner; //# sourceMappingURL=migration-runner.js.map