0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-27 22:49:56 -05:00
ghost/core/server/data/migration/index.js

166 lines
No EOL
5.5 KiB
JavaScript

var _ = require('underscore'),
when = require('when'),
series = require('when/sequence'),
errors = require('../../errorHandling'),
knex = require('../../models/base').Knex,
initialVersion = '000',
// This databaseVersion string should always be the current version of Ghost,
// we could probably load it from the config file.
// - Will be possible after default-settings.json restructure
databaseVersion = '000';
function getDatabaseVersion() {
return knex.Schema.hasTable('settings').then(function () {
// Check for the databaseVersion from the settings table
return knex('settings')
.where('key', 'databaseVersion')
.select('value')
.then(function (databaseVersionSetting) {
if (databaseVersionSetting && databaseVersionSetting.length > 0) {
databaseVersionSetting = databaseVersionSetting[0].value;
} else {
// we didn't get a response we understood, assume initialVersion
databaseVersionSetting = initialVersion;
}
return databaseVersionSetting;
});
});
}
module.exports = {
databaseVersion: databaseVersion,
// Check for whether data is needed to be bootstrapped or not
init: function () {
var self = this;
return getDatabaseVersion().then(function (databaseVersionSetting) {
// We are assuming here that the databaseVersionSetting will
// always be less than the databaseVersion value.
if (databaseVersionSetting === databaseVersion) {
return when.resolve();
}
// Bring the data up to the latest version
return self.migrateUpFromVersion(databaseVersion);
}, function () {
// If the settings table doesn't exist, bring everything up from initial version.
return self.migrateUpFromVersion(initialVersion);
});
},
// ### Reset
// Migrate from where we are down to nothing.
reset: function () {
var self = this;
return getDatabaseVersion().then(function (databaseVersionSetting) {
// bring everything down from the databaseVersion
return self.migrateDownFromVersion(databaseVersionSetting);
}, function () {
// If the settings table doesn't exist, bring everything down from initial version.
return self.migrateDownFromVersion(initialVersion);
});
},
// Migrate from a specific version to the latest
migrateUpFromVersion: function (version, max) {
var versions = [],
maxVersion = max || this.getVersionAfter(databaseVersion),
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);
},
migrateDownFromVersion: function (version) {
var versions = [],
minVersion = this.getVersionBefore(initialVersion),
currVersion = version,
tasks = [];
// Aggregate all the versions we need to do migrations for
while (currVersion !== minVersion) {
versions.push(currVersion);
currVersion = this.getVersionBefore(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.down();
} 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;
},
getVersionBefore: function (currVersion) {
var currVersionNum = parseInt(currVersion, 10),
prevVersion;
if (isNaN(currVersionNum)) {
currVersionNum = parseInt(initialVersion, 10);
}
currVersionNum -= 1;
prevVersion = String(currVersionNum);
// Pad with 0's until 3 digits
while (prevVersion.length < 3) {
prevVersion = "0" + prevVersion;
}
return prevVersion;
}
};