From 5804c0db337ecf492fc61b98a3de7b730a0d8ce3 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 18 Feb 2017 11:56:28 +0100 Subject: [PATCH] Server: fix migration scripts --- server.js | 30 +++++----- server/initializers/constants.js | 8 +-- .../initializers/migrations/0005-email-pod.js | 35 +++++++++--- .../migrations/0010-email-user.js | 41 ++++++++++++++ server/initializers/migrator.js | 56 +++++++++++++------ server/models/user.js | 2 +- 6 files changed, 130 insertions(+), 42 deletions(-) create mode 100644 server/initializers/migrations/0010-email-user.js diff --git a/server.js b/server.js index 4a0de72bb..33d399786 100644 --- a/server.js +++ b/server.js @@ -20,7 +20,7 @@ const constants = require('./server/initializers/constants') const logger = require('./server/helpers/logger') // Initialize database and models const db = require('./server/initializers/database') -db.init() +db.init(onDatabaseInitDone) // ----------- Checker ----------- const checker = require('./server/initializers/checker') @@ -119,25 +119,27 @@ app.use(function (err, req, res, next) { // ----------- Run ----------- -const port = constants.CONFIG.LISTEN.PORT -installer.installApplication(function (err) { - if (err) throw err - - // Run the migration scripts if needed +function onDatabaseInitDone () { + const port = constants.CONFIG.LISTEN.PORT + // Run the migration scripts if needed migrator.migrate(function (err) { if (err) throw err - // ----------- Make the server listening ----------- - server.listen(port, function () { - // Activate the communication with friends - friends.activate() + installer.installApplication(function (err) { + if (err) throw err - logger.info('Server listening on port %d', port) - logger.info('Webserver: %s', constants.CONFIG.WEBSERVER.URL) + // ----------- Make the server listening ----------- + server.listen(port, function () { + // Activate the communication with friends + friends.activate() - app.emit('ready') + logger.info('Server listening on port %d', port) + logger.info('Webserver: %s', constants.CONFIG.WEBSERVER.URL) + + app.emit('ready') + }) }) }) -}) +} module.exports = app diff --git a/server/initializers/constants.js b/server/initializers/constants.js index eb0509efe..821580893 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -5,6 +5,10 @@ const path = require('path') // --------------------------------------------------------------------------- +const LAST_MIGRATION_VERSION = 10 + +// --------------------------------------------------------------------------- + // API version const API_VERSION = 'v1' @@ -95,10 +99,6 @@ const FRIEND_SCORE = { // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 5 - -// --------------------------------------------------------------------------- - // Number of points we add/remove from a friend after a successful/bad request const PODS_SCORE = { MALUS: -10, diff --git a/server/initializers/migrations/0005-email-pod.js b/server/initializers/migrations/0005-email-pod.js index d90b674a1..9bbb354bf 100644 --- a/server/initializers/migrations/0005-email-pod.js +++ b/server/initializers/migrations/0005-email-pod.js @@ -1,18 +1,39 @@ -/* - This is just an example. -*/ +'use strict' -// utils = { transaction, queryInterface } -exports.up = function (utils, callback) { +const waterfall = require('async/waterfall') + +// utils = { transaction, queryInterface, sequelize, Sequelize } +exports.up = function (utils, finalCallback) { const q = utils.queryInterface const Sequelize = utils.Sequelize const data = { type: Sequelize.STRING(400), - allowNull: false + allowNull: false, + defaultValue: '' } - q.addColumn('Pods', 'email', data, { transaction: utils.transaction }).asCallback(callback) + waterfall([ + + function addEmailColumn (callback) { + q.addColumn('Pods', 'email', data, { transaction: utils.transaction }).asCallback(function (err) { + return callback(err) + }) + }, + + function updateWithFakeEmails (callback) { + const query = 'UPDATE "Pods" SET "email" = \'dummy@example.com\'' + utils.sequelize.query(query, { transaction: utils.transaction }).asCallback(function (err) { + return callback(err) + }) + }, + + function nullOnDefault (callback) { + data.defaultValue = null + + q.changeColumn('Pods', 'email', data, { transaction: utils.transaction }).asCallback(callback) + } + ], finalCallback) } exports.down = function (options, callback) { diff --git a/server/initializers/migrations/0010-email-user.js b/server/initializers/migrations/0010-email-user.js new file mode 100644 index 000000000..1ab27133a --- /dev/null +++ b/server/initializers/migrations/0010-email-user.js @@ -0,0 +1,41 @@ +'use strict' + +const waterfall = require('async/waterfall') + +// utils = { transaction, queryInterface, sequelize, Sequelize } +exports.up = function (utils, finalCallback) { + const q = utils.queryInterface + const Sequelize = utils.Sequelize + + const data = { + type: Sequelize.STRING(400), + allowNull: false, + defaultValue: '' + } + + waterfall([ + + function addEmailColumn (callback) { + q.addColumn('Users', 'email', data, { transaction: utils.transaction }).asCallback(function (err) { + return callback(err) + }) + }, + + function updateWithFakeEmails (callback) { + const query = 'UPDATE "Users" SET "email" = CONCAT("username", \'@example.com\')' + utils.sequelize.query(query, { transaction: utils.transaction }).asCallback(function (err) { + return callback(err) + }) + }, + + function nullOnDefault (callback) { + data.defaultValue = null + + q.changeColumn('Users', 'email', data, { transaction: utils.transaction }).asCallback(callback) + } + ], finalCallback) +} + +exports.down = function (options, callback) { + throw new Error('Not implemented.') +} diff --git a/server/initializers/migrator.js b/server/initializers/migrator.js index 233ee2bdd..8c67903ad 100644 --- a/server/initializers/migrator.js +++ b/server/initializers/migrator.js @@ -1,5 +1,6 @@ 'use strict' +const waterfall = require('async/waterfall') const eachSeries = require('async/eachSeries') const fs = require('fs') const path = require('path') @@ -12,30 +13,52 @@ const migrator = { migrate: migrate } -function migrate (callback) { - db.Application.loadMigrationVersion(function (err, actualVersion) { - if (err) return callback(err) +function migrate (finalCallback) { + waterfall([ - // If there are a new migration scripts - if (actualVersion < constants.LAST_MIGRATION_VERSION) { + function checkApplicationTableExists (callback) { + db.sequelize.getQueryInterface().showAllTables().asCallback(function (err, tables) { + if (err) return callback(err) + + // No tables, we don't need to migrate anything + // The installer will do that + if (tables.length === 0) return finalCallback(null) + + return callback(null) + }) + }, + + function loadMigrationVersion (callback) { + db.Application.loadMigrationVersion(callback) + }, + + function abortMigrationIfNotNeeded (actualVersion, callback) { + // No need migrations + if (actualVersion >= constants.LAST_MIGRATION_VERSION) return finalCallback(null) + + return callback(null, actualVersion) + }, + + function getMigrations (actualVersion, callback) { + // If there are a new migration scripts logger.info('Begin migrations.') getMigrationScripts(function (err, migrationScripts) { + return callback(err, actualVersion, migrationScripts) + }) + }, + + function doMigrations (actualVersion, migrationScripts, callback) { + eachSeries(migrationScripts, function (entity, callbackEach) { + executeMigration(actualVersion, entity, callbackEach) + }, function (err) { if (err) return callback(err) - eachSeries(migrationScripts, function (entity, callbackEach) { - executeMigration(actualVersion, entity, callbackEach) - }, function (err) { - if (err) return callback(err) - - logger.info('Migrations finished. New migration version schema: %s', constants.LAST_MIGRATION_VERSION) - return callback(null) - }) + logger.info('Migrations finished. New migration version schema: %s', constants.LAST_MIGRATION_VERSION) + return callback(null) }) - } else { - return callback(null) } - }) + ], finalCallback) } // --------------------------------------------------------------------------- @@ -81,6 +104,7 @@ function executeMigration (actualVersion, entity, callback) { const options = { transaction: t, queryInterface: db.sequelize.getQueryInterface(), + sequelize: db.sequelize, Sequelize: db.Sequelize } migrationScript.up(options, function (err) { diff --git a/server/models/user.js b/server/models/user.js index 35a98dd6b..24e710fa7 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -33,7 +33,7 @@ module.exports = function (sequelize, DataTypes) { } }, email: { - type: DataTypes.STRING, + type: DataTypes.STRING(400), allowNull: false, validate: { isEmail: true