From 4b7671968e0c5032604ccf97bdaa593767e6b9e1 Mon Sep 17 00:00:00 2001 From: Guillaume Chau Date: Fri, 23 Aug 2019 02:31:44 +0200 Subject: [PATCH] feat: db migrations --- packages/@nodepack/db-migrator/package.json | 30 ++++++++++++++ packages/@nodepack/db-migrator/src/index.js | 1 + .../@nodepack/db-migrator/src/lib/Migrator.js | 40 +++++++++++++++++++ .../@nodepack/db-migrator/types/index.d.ts | 1 + .../env-migrator/src/lib/MigrationAPI.js | 0 .../env-migrator/src/lib/Migrator.js | 6 ++- packages/@nodepack/maintenance/package.json | 1 + .../maintenance/src/lib/Maintenance.js | 37 +++++++++++++++-- 8 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 packages/@nodepack/db-migrator/package.json create mode 100644 packages/@nodepack/db-migrator/src/index.js create mode 100644 packages/@nodepack/db-migrator/src/lib/Migrator.js create mode 100644 packages/@nodepack/db-migrator/types/index.d.ts delete mode 100644 packages/@nodepack/env-migrator/src/lib/MigrationAPI.js diff --git a/packages/@nodepack/db-migrator/package.json b/packages/@nodepack/db-migrator/package.json new file mode 100644 index 0000000..62db861 --- /dev/null +++ b/packages/@nodepack/db-migrator/package.json @@ -0,0 +1,30 @@ +{ + "name": "@nodepack/db-migrator", + "version": "0.4.4", + "description": "Database Migration system for Nodepack", + "author": "Guillaume Chau ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/Akryum/nodepack.git" + }, + "bugs": { + "url": "https://github.com/Akryum/nodepack/issues" + }, + "homepage": "https://github.com/Akryum/nodepack#readme", + "publishConfig": { + "access": "public" + }, + "main": "src/index.js", + "typings": "types/index.d.ts", + "scripts": { + "test": "yarn test:lint", + "test:lint": "eslint src" + }, + "dependencies": { + "@nodepack/env-migrator": "^0.4.4" + }, + "devDependencies": { + "@nodepack/service": "^0.4.4" + } +} diff --git a/packages/@nodepack/db-migrator/src/index.js b/packages/@nodepack/db-migrator/src/index.js new file mode 100644 index 0000000..41a8708 --- /dev/null +++ b/packages/@nodepack/db-migrator/src/index.js @@ -0,0 +1 @@ +exports.Migrator = require('./lib/Migrator') diff --git a/packages/@nodepack/db-migrator/src/lib/Migrator.js b/packages/@nodepack/db-migrator/src/lib/Migrator.js new file mode 100644 index 0000000..9244f92 --- /dev/null +++ b/packages/@nodepack/db-migrator/src/lib/Migrator.js @@ -0,0 +1,40 @@ +/** + * @typedef FileMigrationRecord + * @prop {string} file + * @prop {string} date + */ + +const { Migrator: EnvMigrator } = require('@nodepack/env-migrator') + +module.exports = class Migrator extends EnvMigrator { + /** + * @private + */ + async setup () { + await this.readMigrationRecords() + } + + /** + * @private + */ + async readMigrationRecords () { + if (!this.context.readDbMigrationRecords) { + throw new Error(`No 'readDbMigrationRecords' method provided by context`) + } + const data = await this.context.readDbMigrationRecords() + this.fileMigrationRecords = data.files + } + + /** + * @private + */ + async writeMigrationRecords () { + if (!this.context.writeDbMigrationRecords) { + throw new Error(`No 'writeDbMigrationRecords' method provided by context`) + } + await this.context.writeDbMigrationRecords({ + files: this.fileMigrationRecords, + plugins: [], + }) + } +} diff --git a/packages/@nodepack/db-migrator/types/index.d.ts b/packages/@nodepack/db-migrator/types/index.d.ts new file mode 100644 index 0000000..548959d --- /dev/null +++ b/packages/@nodepack/db-migrator/types/index.d.ts @@ -0,0 +1 @@ +export { default as Migrator } from '../src/lib/Migrator' diff --git a/packages/@nodepack/env-migrator/src/lib/MigrationAPI.js b/packages/@nodepack/env-migrator/src/lib/MigrationAPI.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/@nodepack/env-migrator/src/lib/Migrator.js b/packages/@nodepack/env-migrator/src/lib/Migrator.js index 6452981..d78aca1 100644 --- a/packages/@nodepack/env-migrator/src/lib/Migrator.js +++ b/packages/@nodepack/env-migrator/src/lib/Migrator.js @@ -22,9 +22,11 @@ module.exports = class Migrator { */ constructor (cwd, { migrationsFolder, + context, }) { this.cwd = cwd this.migrationsFolder = migrationsFolder + this.context = context /** @type {FileMigrationRecord[]} */ this.fileMigrationRecords = [] this.upPrepared = false @@ -46,7 +48,7 @@ module.exports = class Migrator { } } - async up (context) { + async up () { await this.prepareUp() // Files @@ -55,7 +57,7 @@ module.exports = class Migrator { if (module.up) { try { logWithSpinner('✔️', chalk.grey(module.file)) - await module.up(context) + await module.up(this.context) stopSpinner() this.fileMigrationRecords.push({ file: module.file, diff --git a/packages/@nodepack/maintenance/package.json b/packages/@nodepack/maintenance/package.json index e9a579b..35fc128 100644 --- a/packages/@nodepack/maintenance/package.json +++ b/packages/@nodepack/maintenance/package.json @@ -23,6 +23,7 @@ "dependencies": { "@nodepack/app-migrator": "^0.4.3", "@nodepack/env-migrator": "^0.4.3", + "@nodepack/db-migrator": "^0.4.4", "@nodepack/fragment": "^0.4.2", "@nodepack/hookable": "^0.4.2", "@nodepack/utils": "^0.4.3", diff --git a/packages/@nodepack/maintenance/src/lib/Maintenance.js b/packages/@nodepack/maintenance/src/lib/Maintenance.js index f0d3c86..04f4c1b 100644 --- a/packages/@nodepack/maintenance/src/lib/Maintenance.js +++ b/packages/@nodepack/maintenance/src/lib/Maintenance.js @@ -3,6 +3,7 @@ const { Migrator: AppMigrator, getMigratorPlugins: getAppMigratorPlugins } = require('@nodepack/app-migrator') const { Migrator: EnvMigrator } = require('@nodepack/env-migrator') +const { Migrator: DbMigrator } = require('@nodepack/db-migrator') const { log, error, @@ -28,6 +29,7 @@ const FRAGMENTS = [ ] const ENV_MIGRATION_FOLDER = 'migration/env' +const DB_MIGRATION_FOLDER = 'migration/db' /** * @typedef MaintenanceHookAPI @@ -67,6 +69,7 @@ const ENV_MIGRATION_FOLDER = 'migration/env' * @prop {AppMigrationAllOptions?} appMigrationAllOptions * @prop {number} appMigrationCount * @prop {number} envMigrationCount + * @prop {number} dbMigrationCount */ /** @@ -114,6 +117,7 @@ class Maintenance { appMigrationAllOptions: null, appMigrationCount: 0, envMigrationCount: 0, + dbMigrationCount: 0, } /** @type {function[]} */ this.completeCbs = [] @@ -138,10 +142,18 @@ class Maintenance { await this.runAppMigrations() await this.callHook('afterAppMigrations') + // Prepare context + await this.buildFragments(FRAGMENTS) + await this.createContext() + // Env Migrations await this.runEnvMigrations() await this.callHook('afterEnvMigrations') + // Database Migrations + await this.runDbMigrations() + await this.callHook('afterDbMigrations') + log(`🔧 Maintenance complete!`) await this.callHook('after') @@ -174,17 +186,16 @@ class Maintenance { } async runEnvMigrations () { - const { cwd } = this + const { cwd, context } = this const migrator = new EnvMigrator(cwd, { migrationsFolder: ENV_MIGRATION_FOLDER, + context, }) const { files } = await migrator.prepareUp() if (files.length) { - await this.buildFragments(FRAGMENTS) - await this.createContext() await this.shouldCommitState(`[nodepack] before env migration`) log(`🚀 Migrating env...`) - const { migrationCount } = await migrator.up(this.context) + const { migrationCount } = await migrator.up() log(`💻️ ${migrationCount} env migration${migrationCount > 1 ? 's' : ''} applied!`) this.results.envMigrationCount = migrationCount // install additional deps (injected by migrations) @@ -193,6 +204,24 @@ class Maintenance { } } + async runDbMigrations () { + const { cwd, context } = this + if (!context.readDbMigrationRecords) return + const migrator = new DbMigrator(cwd, { + migrationsFolder: DB_MIGRATION_FOLDER, + context, + }) + const { files } = await migrator.prepareUp() + if (files.length) { + await this.shouldCommitState(`[nodepack] before db migration`) + log(`🚀 Migrating db...`) + const { migrationCount } = await migrator.up() + log(`🗄️ ${migrationCount} db migration${migrationCount > 1 ? 's' : ''} applied!`) + this.results.dbMigrationCount = migrationCount + await this.shouldCommitState(`[nodepack] after db migration`) + } + } + /** * @param {string} id */