diff --git a/core/server/data/migrations/versions/3.0/1-add-type-column.js b/core/server/data/migrations/versions/3.0/1-add-type-column.js new file mode 100644 index 0000000000..d525b80b33 --- /dev/null +++ b/core/server/data/migrations/versions/3.0/1-add-type-column.js @@ -0,0 +1,44 @@ +const common = require('../../../../lib/common'); +const commands = require('../../../schema').commands; + +const createLog = type => msg => common.logging[type](msg); + +function createColumnMigration({table, column, dbIsInCorrectState, operation, operationVerb}) { + return function columnMigrations({transacting}) { + return transacting.schema.hasColumn(table, column) + .then(dbIsInCorrectState) + .then((isInCorrectState) => { + const log = createLog(isInCorrectState ? 'warn' : 'info'); + + log(`${operationVerb} ${table}.${column}`); + + if (!isInCorrectState) { + return operation(table, column, transacting); + } + }); + }; +} + +module.exports.up = createColumnMigration({ + table: 'posts', + column: 'type', + dbIsInCorrectState(columnExists) { + return columnExists === true; + }, + operation: commands.addColumn, + operationVerb: 'Adding' +}); + +module.exports.down = createColumnMigration({ + table: 'posts', + column: 'type', + dbIsInCorrectState(columnExists) { + return columnExists === false; + }, + operation: commands.dropColumn, + operationVerb: 'Removing' +}); + +module.exports.config = { + transaction: true +}; diff --git a/core/server/data/migrations/versions/3.0/2-populate-type-column.js b/core/server/data/migrations/versions/3.0/2-populate-type-column.js new file mode 100644 index 0000000000..b0918574c1 --- /dev/null +++ b/core/server/data/migrations/versions/3.0/2-populate-type-column.js @@ -0,0 +1,94 @@ +const Promise = require('bluebird'); +const toPairs = require('lodash/toPairs'); +const common = require('../../../../lib/common'); + +/* + * @param from: object with a SINGLE entry { 'fromColumn': 'fromValue' } + * @param to: object with a SINGLE entry { 'toColumn': 'toValue' } + */ +const createColumnToColumnMap = ({from, to, tableName}) => (connection) => { + return connection.schema.hasTable(tableName) + .then((tableExists) => { + if (!tableExists) { + common.logging.warn( + `Table ${tableName} does not exist` + ); + return; + } + + const [fromColumn, fromValue] = toPairs(from)[0]; + const [toColumn, toValue] = toPairs(to)[0]; + + return Promise.all([ + connection.schema.hasColumn(tableName, fromColumn), + connection.schema.hasColumn(tableName, toColumn) + ]).then(([fromColumnExists, toColumnExists]) => { + if (!fromColumnExists) { + common.logging.warn( + `Table '${tableName}' does not have column '${fromColumn}'` + ); + } + if (!toColumnExists) { + common.logging.warn( + `Table '${tableName}' does not have column '${toColumn}'` + ); + } + if (!fromColumnExists || !toColumnExists) { + return; + } + + common.logging.info( + `Updating ${tableName}, setting "${toColumn}" column to "${toValue}" where "${fromColumn}" column is "${fromValue}"` + ); + + return connection(tableName) + .where(fromColumn, fromValue) + .update(toColumn, toValue); + }); + }); +}; + +const createColumnToColumnMigration = ({tableName, from, to}) => { + return { + up: createColumnToColumnMap({from, to, tableName}), + down: createColumnToColumnMap({from: to, to: from, tableName}) + }; +}; + +const pageColumnToPageType = createColumnToColumnMigration({ + tableName: 'posts', + from: { + page: true + }, + to: { + type: 'page' + } +}); + +const pageColumnToPostType = createColumnToColumnMigration({ + tableName: 'posts', + from: { + page: false + }, + to: { + type: 'post' + } +}); + +module.exports.up = ({transacting}) => { + return Promise.all([ + pageColumnToPageType.up(transacting), + pageColumnToPostType.up(transacting) + ]); +}; + +module.exports.down = ({transacting}) => { + return Promise.all([ + pageColumnToPageType.down(transacting), + pageColumnToPostType.down(transacting) + ]); +}; + +module.exports.config = { + transaction: true +}; diff --git a/core/server/data/migrations/versions/3.0/3-remove-page-column.js b/core/server/data/migrations/versions/3.0/3-remove-page-column.js new file mode 100644 index 0000000000..c6fd1fbfef --- /dev/null +++ b/core/server/data/migrations/versions/3.0/3-remove-page-column.js @@ -0,0 +1,44 @@ +const common = require('../../../../lib/common'); +const commands = require('../../../schema').commands; + +const createLog = type => msg => common.logging[type](msg); + +function createColumnMigration({table, column, dbIsInCorrectState, operation, operationVerb}) { + return function columnMigrations({transacting}) { + return transacting.schema.hasColumn(table, column) + .then(dbIsInCorrectState) + .then((isInCorrectState) => { + const log = createLog(isInCorrectState ? 'warn' : 'info'); + + log(`${operationVerb} ${table}.${column}`); + + if (!isInCorrectState) { + return operation(table, column, transacting); + } + }); + }; +} + +module.exports.up = createColumnMigration({ + table: 'posts', + column: 'page', + dbIsInCorrectState(columnExists) { + return columnExists === false; + }, + operation: commands.dropColumn, + operationVerb: 'Removing' +}); + +module.exports.down = createColumnMigration({ + table: 'posts', + column: 'page', + dbIsInCorrectState(columnExists) { + return columnExists === true; + }, + operation: commands.addColumn, + operationVerb: 'Adding' +}); + +module.exports.config = { + transaction: true +};