| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- const _ = require('lodash')
- const sequelize = require('./sequelize')
- const Sequelize = require('sequelize')
- const migrations = require('./migrations')
- const chalk = require('chalk')
- const Version = sequelize.define('_version', {
- key: {
- type: Sequelize.STRING,
- primaryKey: true
- },
- value: Sequelize.DOUBLE
- }, {
- tableName: '_version',
- timestamps: false
- })
- const getVersion = async (namespace, queryInterface) => {
- const defaultVersion = migrations[namespace].defaultVersion || migrations[namespace].map(x => x.version).reduce((a, b) => Math.max(a, b), 0.0)
- const tables = await queryInterface.showAllTables()
- if (!tables.includes('_version')) {
- return defaultVersion
- } else {
- const result = await Version.findOne({where: {key: namespace}})
- if (result) {
- return result.value
- } else {
- return defaultVersion
- }
- }
- }
- const setVersion = async (namespace, version, queryInterface) => {
- await Version.upsert({key: namespace, value: version}, { where: { key: namespace }})
- }
- const migrate = async (namespace, targetVersion) => {
- const queryInterface = sequelize.getQueryInterface()
- const currentVersion = await getVersion(namespace, queryInterface)
- let migs = _.sortBy(migrations[namespace], 'version')
- if (!targetVersion) targetVersion = migs.map(x => x.version).reduce((a, b) => Math.max(a, b), 0)
- console.log(chalk.green(`Migrating ${namespace}`))
- console.log(chalk.yellow(`Current version: ${currentVersion}`))
- console.log(chalk.yellow(`Target version: ${targetVersion}`))
- // Sanity check
- for (let mig of migs) {
- if (!mig.version) throw new Error(`All migrations require versions`)
- if (!mig.up) throw new Error('All migrations require `up`')
- }
- // Filter to relevant migrations
- migs = migs.filter(mig => mig.version > currentVersion && mig.version <= targetVersion)
- console.log(`Migrations to run: ${migs.map(x => x.version).join(', ')}`)
- let lastVersion = currentVersion
- for (let mig of migs) {
- if (mig.version > lastVersion) {
- console.log(chalk.blue(`Running migration ${mig.version}: ${mig.name}`))
- mig.description && console.log(chalk.blue(mig.description))
- let newVersion = await mig.up(queryInterface, Sequelize)
- if (!Number.isFinite(newVersion)) throw new Error(`All migrations must return the resulting version`)
- if (newVersion < lastVersion) throw new Error(`Up migration downgraded database: ${mig.version} -> ${newVersion}`)
- await setVersion(namespace, newVersion, queryInterface)
- console.log(`Database now at version ${newVersion}`)
- lastVersion = newVersion
- } else {
- console.log(chalk.blue(`Skipping migration ${mig.version}: ${mig.name}`))
- }
- }
- console.log(chalk.cyan(`Migration complete. Current database version: ${await getVersion(namespace, queryInterface)}`))
- }
- const migrateAll = async () => {
- const namespaces = _.keys(_.omit(migrations, 'material-framework'))
- await migrate('material-framework')
- console.log(_.keys(migrations))
- for (let namespace of namespaces) {
- await migrate(namespace)
- }
- }
- module.exports = {
- getVersion,
- migrate,
- migrateAll,
- migrations,
- setVersion
- }
|