diff --git a/core/server/data/export/index.js b/core/server/data/export/index.js index 0c974c9af8..e220772c9c 100644 --- a/core/server/data/export/index.js +++ b/core/server/data/export/index.js @@ -1,8 +1,8 @@ -var when = require('when'), - _ = require('lodash'), - migration = require('../migration'), - knex = require('../../models/base').knex, - schema = require('../schema').tables, +var _ = require('lodash'), + when = require('when'), + versioning = require('../versioning'), + knex = require('../../models/base').knex, + schema = require('../schema').tables, excludedTables = ['sessions'], exporter; @@ -10,7 +10,7 @@ var when = require('when'), exporter = function () { var tablesToExport = _.keys(schema); - return when.join(migration.getDatabaseVersion(), tablesToExport).then(function (results) { + return when.join(versioning.getDatabaseVersion(), tablesToExport).then(function (results) { var version = results[0], tables = results[1], selectOps = _.map(tables, function (name) { diff --git a/core/server/data/migration/index.js b/core/server/data/migration/index.js index d9e9df8102..924f28e485 100644 --- a/core/server/data/migration/index.js +++ b/core/server/data/migration/index.js @@ -1,18 +1,20 @@ var _ = require('lodash'), when = require('when'), + path = require('path'), + fs = require('fs'), + nodefn = require('when/node/function'), errors = require('../../errors'), client = require('../../models/base').client, knex = require('../../models/base').knex, sequence = require('when/sequence'), - defaultSettings = require('../default-settings'), + versioning = require('../versioning'), Settings = require('../../models/settings').Settings, fixtures = require('../fixtures'), schema = require('../schema').tables, + dataExport = require('../export'), - initialVersion = '000', schemaTables = _.keys(schema), - defaultDatabaseVersion, init, reset, @@ -20,58 +22,6 @@ var _ = require('lodash'), migrateUpFreshDb, getTables; -// Default Database Version -// The migration version number according to the hardcoded default settings -// This is the version the database should be at or migrated to -function getDefaultDatabaseVersion() { - if (!defaultDatabaseVersion) { - // This be the current version according to the software - defaultDatabaseVersion = _.find(defaultSettings.core, function (setting) { - return setting.key === 'databaseVersion'; - }).defaultValue; - } - - return defaultDatabaseVersion; -} - -// Database Current Version -// The migration version number according to the database -// This is what the database is currently at and may need to be updated -function getDatabaseVersion() { - return knex.schema.hasTable('settings').then(function (exists) { - // Check for the current version from the settings table - if (exists) { - // Temporary code to deal with old databases with currentVersion settings - return knex('settings') - .where('key', 'databaseVersion') - .orWhere('key', 'currentVersion') - .select('value') - .then(function (versions) { - var databaseVersion = _.reduce(versions, function (memo, version) { - if (isNaN(version.value)) { - errors.throwError('Database version is not recognised'); - } - return parseInt(version.value, 10) > parseInt(memo, 10) ? version.value : memo; - }, initialVersion); - - if (!databaseVersion || databaseVersion.length === 0) { - // we didn't get a response we understood, assume initialVersion - databaseVersion = initialVersion; - } - - return databaseVersion; - }); - } - throw new Error('Settings table does not exist'); - }); -} - -function setDatabaseVersion() { - return knex('settings') - .where('key', 'databaseVersion') - .update({ 'value': defaultDatabaseVersion }); -} - function createTable(table) { return knex.schema.createTable(table, function (t) { var column, @@ -168,8 +118,8 @@ init = function () { // 2. The database exists but is out of date // 3. The database exists but the currentVersion setting does not or cannot be understood // 4. The database has not yet been created - return getDatabaseVersion().then(function (databaseVersion) { - var defaultVersion = getDefaultDatabaseVersion(); + return versioning.getDatabaseVersion().then(function (databaseVersion) { + var defaultVersion = versioning.getDefaultDatabaseVersion(); if (databaseVersion === defaultVersion) { // 1. The database exists and is up-to-date return when.resolve(); @@ -179,7 +129,7 @@ init = function () { // Migrate to latest version return self.migrateUp().then(function () { // Finally update the databases current version - return setDatabaseVersion(); + return versioning.setDatabaseVersion(); }); } if (databaseVersion > defaultVersion) { @@ -249,9 +199,20 @@ function checkMySQLPostTable() { }); } +function backupDatabase() { + return dataExport().then(function (exportedData) { + // Save the exported data to the file system for download + var fileName = path.resolve(__dirname + '/../exported-' + (new Date().getTime()) + '.json'); + + return nodefn.call(fs.writeFile, fileName, JSON.stringify(exportedData)); + }); +} + // Migrate from a specific version to the latest migrateUp = function () { - return getTables().then(function (oldTables) { + return backupDatabase().then(function () { + return getTables(); + }).then(function (oldTables) { // if tables exist and client is mysqls check if posts table is okay if (!_.isEmpty(oldTables) && client === 'mysql') { return checkMySQLPostTable().then(function () { @@ -293,7 +254,6 @@ getTables = function () { }; module.exports = { - getDatabaseVersion: getDatabaseVersion, init: init, reset: reset, migrateUp: migrateUp, diff --git a/core/server/data/versioning/index.js b/core/server/data/versioning/index.js new file mode 100644 index 0000000000..950caaea5d --- /dev/null +++ b/core/server/data/versioning/index.js @@ -0,0 +1,66 @@ +var _ = require('lodash'), + errors = require('../../errors'), + knex = require('../../models/base').knex, + + defaultSettings = require('../default-settings'), + + initialVersion = '000', + defaultDatabaseVersion; + +// Default Database Version +// The migration version number according to the hardcoded default settings +// This is the version the database should be at or migrated to +function getDefaultDatabaseVersion() { + if (!defaultDatabaseVersion) { + // This be the current version according to the software + defaultDatabaseVersion = _.find(defaultSettings.core, function (setting) { + return setting.key === 'databaseVersion'; + }).defaultValue; + } + + return defaultDatabaseVersion; +} + +// Database Current Version +// The migration version number according to the database +// This is what the database is currently at and may need to be updated +function getDatabaseVersion() { + return knex.schema.hasTable('settings').then(function (exists) { + // Check for the current version from the settings table + if (exists) { + // Temporary code to deal with old databases with currentVersion settings + return knex('settings') + .where('key', 'databaseVersion') + .orWhere('key', 'currentVersion') + .select('value') + .then(function (versions) { + var databaseVersion = _.reduce(versions, function (memo, version) { + if (isNaN(version.value)) { + errors.throwError('Database version is not recognised'); + } + return parseInt(version.value, 10) > parseInt(memo, 10) ? version.value : memo; + }, initialVersion); + + if (!databaseVersion || databaseVersion.length === 0) { + // we didn't get a response we understood, assume initialVersion + databaseVersion = initialVersion; + } + + return databaseVersion; + }); + } + throw new Error('Settings table does not exist'); + }); +} + +function setDatabaseVersion() { + return knex('settings') + .where('key', 'databaseVersion') + .update({ 'value': defaultDatabaseVersion }); +} + +module.exports = { + getDefaultDatabaseVersion: getDefaultDatabaseVersion, + getDatabaseVersion: getDatabaseVersion, + setDatabaseVersion: setDatabaseVersion +}; \ No newline at end of file diff --git a/core/test/unit/export_spec.js b/core/test/unit/export_spec.js index f486abec4d..57bd875bcb 100644 --- a/core/test/unit/export_spec.js +++ b/core/test/unit/export_spec.js @@ -8,6 +8,7 @@ var testUtils = require('../utils'), // Stuff we are testing migration = require('../../server/data/migration'), + versioning = require('../../server/data/versioning'), exporter = require('../../server/data/export'), Settings = require('../../server/models/settings').Settings; @@ -39,7 +40,7 @@ describe("Exporter", function () { it("exports data", function (done) { // Stub migrations to return 000 as the current database version - var migrationStub = sandbox.stub(migration, "getDatabaseVersion", function () { + var versioningStub = sandbox.stub(versioning, "getDatabaseVersion", function () { return when.resolve("003"); }); @@ -61,7 +62,7 @@ describe("Exporter", function () { // should not export sqlite data should.not.exist(exportData.data.sqlite_sequence); - migrationStub.restore(); + versioningStub.restore(); done(); }).catch(done); }); diff --git a/core/test/unit/import_spec.js b/core/test/unit/import_spec.js index 1a3dd9c5c3..3add769955 100644 --- a/core/test/unit/import_spec.js +++ b/core/test/unit/import_spec.js @@ -8,8 +8,9 @@ var testUtils = require('../utils'), errors = require('../../server/errors'), // Stuff we are testing - knex = require("../../server/models/base").knex, + knex = require('../../server/models/base').knex, migration = require('../../server/data/migration'), + versioning = require('../../server/data/versioning'), exporter = require('../../server/data/export'), importer = require('../../server/data/import'), Importer000 = require('../../server/data/import/000'), @@ -113,7 +114,7 @@ describe("Import", function () { it("imports data from 000", function (done) { var exportData, - migrationStub = sandbox.stub(migration, "getDatabaseVersion", function () { + versioningStub = sandbox.stub(versioning, "getDatabaseVersion", function () { return when.resolve("000"); }); @@ -151,7 +152,7 @@ describe("Import", function () { // test tags tags.length.should.equal(exportData.data.tags.length, 'no new tags'); - migrationStub.restore(); + versioningStub.restore(); done(); }).catch(done);