Skip to content

Commit

Permalink
Magnificent Migrations of Magical Majesty
Browse files Browse the repository at this point in the history
  • Loading branch information
jgable authored and ErisDS committed Aug 3, 2013
1 parent ec1ced9 commit f7568f6
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 11 deletions.
1 change: 0 additions & 1 deletion core/server/data/fixtures/001.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var uuid = require('node-uuid');

/*global module */
module.exports = {
posts: [
{
Expand Down
22 changes: 22 additions & 0 deletions core/server/data/fixtures/002.js
Original file line number Diff line number Diff line change
@@ -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: []
};
41 changes: 41 additions & 0 deletions core/server/data/migration/002.js
Original file line number Diff line number Diff line change
@@ -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;
90 changes: 90 additions & 0 deletions core/server/data/migration/index.js
Original file line number Diff line number Diff line change
@@ -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;
}
};
12 changes: 2 additions & 10 deletions core/server/models/index.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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();
}
};

0 comments on commit f7568f6

Please sign in to comment.