From 9393a956f4af84df02c0e56db54a5921a98b77d2 Mon Sep 17 00:00:00 2001 From: Jacob Gable Date: Sat, 27 Jul 2013 19:41:10 +0000 Subject: [PATCH] Magnificent Migrations of Magical Majesty --- core/server/data/fixtures/001.js | 1 - core/server/data/fixtures/002.js | 22 +++++++ core/server/data/migration/002.js | 41 +++++++++++++ core/server/data/migration/index.js | 90 +++++++++++++++++++++++++++++ core/server/models/index.js | 12 +--- 5 files changed, 155 insertions(+), 11 deletions(-) create mode 100644 core/server/data/fixtures/002.js create mode 100644 core/server/data/migration/002.js create mode 100644 core/server/data/migration/index.js diff --git a/core/server/data/fixtures/001.js b/core/server/data/fixtures/001.js index d48d64cb7e..060d312171 100644 --- a/core/server/data/fixtures/001.js +++ b/core/server/data/fixtures/001.js @@ -1,6 +1,5 @@ var uuid = require('node-uuid'); -/*global module */ module.exports = { posts: [ { diff --git a/core/server/data/fixtures/002.js b/core/server/data/fixtures/002.js new file mode 100644 index 0000000000..ff436f5705 --- /dev/null +++ b/core/server/data/fixtures/002.js @@ -0,0 +1,22 @@ +var uuid = require('node-uuid'); + +module.exports = { + posts: [], + + settings: [ + { + "uuid": uuid.v4(), + "key": "installedPlugins", + "value": "[]", + "created_by": 1, + "updated_by": 1, + "type": "core" + } + ], + + roles: [], + + permissions: [], + + permissions_roles: [] +}; \ No newline at end of file diff --git a/core/server/data/migration/002.js b/core/server/data/migration/002.js new file mode 100644 index 0000000000..7301ae95b4 --- /dev/null +++ b/core/server/data/migration/002.js @@ -0,0 +1,41 @@ +var when = require('when'), + knex = require('../../models/base').Knex, + migrationVersion = '002', + fixtures = require('../fixtures/' + migrationVersion), + errors = require('../../errorHandling'), + up, + down; + +up = function () { + + return when.all([ + + // TODO: Create tables or modify tables in this general area + + ]).then(function () { + + // Once we create all of the initial tables, bootstrap any of the data + + return when.all([ + //knex('posts').insert(fixtures.posts), + //knex('roles').insert(fixtures.roles), + //knex('permissions').insert(fixtures.permissions), + //knex('permissions_roles').insert(fixtures.permissions_roles), + knex('settings').insert(fixtures.settings) + ]); + + }).then(function () { + + // Lastly, update the current version settings to reflect this version + return knex('settings') + .where('key', 'currentVersion') + .update({ 'value': migrationVersion }); + }); +}; + +down = function () { + return; +}; + +exports.up = up; +exports.down = down; \ No newline at end of file diff --git a/core/server/data/migration/index.js b/core/server/data/migration/index.js new file mode 100644 index 0000000000..9426ff38a5 --- /dev/null +++ b/core/server/data/migration/index.js @@ -0,0 +1,90 @@ + +var _ = require('underscore'), + when = require('when'), + series = require('when/sequence'), + errors = require('../../errorHandling'), + knex = require('../../models/base').Knex, + initialVersion = "001", + // This currentVersion string should always be the current version of Ghost, + // we could probably load it from the config file. + currentVersion = "002"; + +module.exports = { + // Check for whether data is needed to be bootstrapped or not + init: function () { + var that = this; + + return knex.Schema.hasTable('settings').then(function () { + // Check for the current version from the settings table + return knex('settings') + .where('key', 'currentVersion') + .select('value') + .then(function (currentVersionSetting) { + // We are assuming here that the currentVersionSetting will + // always be less than the currentVersion value. + if (currentVersionSetting === currentVersion) { + return when.resolve(); + } + + // Bring the data up to the latest version + return that.migrateFromVersion(currentVersion); + }, errors.logAndThrowError); + + }, function () { + // If the settings table doesn't exist, bring everything up from initial version. + return that.migrateFromVersion(initialVersion); + }); + }, + + // Migrate from a specific version to the latest + migrateFromVersion: function (version) { + var versions = [], + maxVersion = this.getVersionAfter(currentVersion), + currVersion = version, + tasks = []; + + // Aggregate all the versions we need to do migrations for + while (currVersion !== maxVersion) { + versions.push(currVersion); + currVersion = this.getVersionAfter(currVersion); + } + + // Aggregate all the individual up calls to use in the series(...) below + tasks = _.map(versions, function (taskVersion) { + return function () { + try { + var migration = require('./' + taskVersion); + return migration.up(); + } catch (e) { + errors.logError(e); + return when.reject(e); + } + }; + }); + + // Run each migration in series + return series(tasks); + }, + + // Get the following version based on the current + getVersionAfter: function (currVersion) { + + var currVersionNum = parseInt(currVersion, 10), + nextVersion; + + // Default to initialVersion if not parsed + if (isNaN(currVersionNum)) { + currVersionNum = parseInt(initialVersion, 10); + } + + currVersionNum += 1; + + nextVersion = String(currVersionNum); + // Pad with 0's until 3 digits + while (nextVersion.length < 3) { + nextVersion = "0" + nextVersion; + } + + return nextVersion; + } +}; \ No newline at end of file diff --git a/core/server/models/index.js b/core/server/models/index.js index b166ed3205..b3f6e08c5d 100644 --- a/core/server/models/index.js +++ b/core/server/models/index.js @@ -1,6 +1,4 @@ -var GhostBookshelf = require('./base'), - errors = require('../errorHandling'), - knex = GhostBookshelf.Knex; +var migrations = require('../data/migration'); module.exports = { Post: require('./post').Post, @@ -9,12 +7,6 @@ module.exports = { Permission: require('./permission').Permission, Settings: require('./settings').Settings, init: function () { - return knex.Schema.hasTable('posts').then(null, function () { - // Simple bootstraping of the data model for now. - var migration = require('../data/migration/001'); - return migration.down().then(function () { - return migration.up(); - }, errors.logAndThrowError); - }, errors.logAndThrowError); + return migrations.init(); } };