Skip to content

Commit

Permalink
✨ knex-migrator v2 (#7605)
Browse files Browse the repository at this point in the history
* 🎨  knex-migrator reset

[ci skip]

* ✨  add migration example

- hooks
- 1.0

[ci skip]

* 🛠  knex-migrator tarball

- remove when released

[ci skip]

* 🎨  jscs/jshint

* 🕵🏻 do not drop the database connection when running tests

- please read the comments in the commit

* 🔥  remove example migration

* 🛠  knex-migrator 0.1.0

* 🛠  knex-migrator 0.1.1

- fix a single test to ensure we catch the error

* 🛠  knex-migrator 0.1.2

* 🎨  make tests green

- added my keyword: kate-migrations
- i will go over all TODO's when removing the old migrations code

* 🛠  knex-migrator update

* 🛠  knex-migrator 0.2.0
  • Loading branch information
kirrg001 authored and ErisDS committed Nov 7, 2016
1 parent a19fa8d commit bae0de6
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .knex-migrator
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env node

var config = require('./core/server/config');
var config = require('./core/server/config'),
versioning = require('./core/server/data/schema/versioning');

module.exports = {
currentVersion: versioning.getNewestDatabaseVersion(),
database: config.get('database'),
migrationPath: config.get('paths:migrationPath')
}
30 changes: 30 additions & 0 deletions core/server/data/migrations/hooks/init/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var errors = require('../../../../errors'),
config = require('../../../../config'),
versioning = require('../../../schema/versioning'),
database = require('../../../db');

module.exports = function after(options) {
return versioning.getDatabaseVersion(options)
.catch(function (err) {
if (err instanceof errors.DatabaseVersionError && err.code === 'VERSION_DOES_NOT_EXIST') {
return versioning.setDatabaseVersion(options);
}

throw err;
})
.finally(function destroyConnection() {
// do not close database connection in test mode, because all tests are executed one after another
// this check is not nice, but there is only one other solution i can think of:
// forward a custom object to knex-migrator, which get's forwarded to the hooks
if (config.get('env').match(/testing/g)) {
return;
}

// we need to close the database connection
// the after hook signals the last step of a knex-migrator command
// Example:
// Ghost-CLI calls knexMigrator.init and afterwards it starts Ghost, but Ghost-CLI can't shutdown
// if Ghost keeps a connection alive
return database.knex.destroy();
});
};
7 changes: 7 additions & 0 deletions core/server/data/migrations/hooks/init/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var Promise = require('bluebird'),
models = require('../../../../models');

module.exports = function before() {
models.init();
return Promise.resolve();
};
2 changes: 2 additions & 0 deletions core/server/data/migrations/hooks/init/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exports.after = require('./after');
exports.before = require('./before');
30 changes: 30 additions & 0 deletions core/server/data/migrations/hooks/migrate/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var errors = require('../../../../errors'),
config = require('../../../../config'),
versioning = require('../../../schema/versioning'),
database = require('../../../db');

module.exports = function after(options) {
return versioning.getDatabaseVersion(options)
.catch(function (err) {
if (err instanceof errors.DatabaseVersionError && err.code === 'VERSION_DOES_NOT_EXIST') {
return versioning.setDatabaseVersion(options);
}

throw err;
})
.finally(function destroyConnection() {
// do not close database connection in test mode, because all tests are executed one after another
// this check is not nice, but there is only one other solution i can think of:
// forward a custom object to knex-migrator, which get's forwarded to the hooks
if (config.get('env').match(/testing/g)) {
return;
}

// we need to close the database connection
// the after hook signals the last step of a knex-migrator command
// Example:
// Ghost-CLI calls knexMigrator.init and afterwards it starts Ghost, but Ghost-CLI can't shutdown
// if Ghost keeps a connection alive
return database.knex.destroy();
});
};
5 changes: 5 additions & 0 deletions core/server/data/migrations/hooks/migrate/afterEach.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var Promise = require('bluebird');

module.exports = function afterEach() {
return Promise.resolve();
};
7 changes: 7 additions & 0 deletions core/server/data/migrations/hooks/migrate/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var backup = require('../../../schema/backup'),
models = require('../../../../models');

module.exports = function before(options) {
models.init();
return backup(options);
};
5 changes: 5 additions & 0 deletions core/server/data/migrations/hooks/migrate/beforeEach.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var Promise = require('bluebird');

module.exports = function beforeEach() {
return Promise.resolve();
};
4 changes: 4 additions & 0 deletions core/server/data/migrations/hooks/migrate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
exports.before = require('./before');
exports.after = require('./after');
exports.beforeEach = require('./beforeEach');
exports.afterEach = require('./afterEach');
4 changes: 0 additions & 4 deletions core/server/data/migrations/init/2-create-fixtures.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
var Promise = require('bluebird'),
_ = require('lodash'),
fixtures = require('../../schema/fixtures'),
models = require('../../../models'),
logging = require('../../../logging');

// @TODO: models.init
module.exports = function insertFixtures(options) {
var localOptions = _.merge({
context: {internal: true}
}, options);

models.init();

return Promise.mapSeries(fixtures.models, function (model) {
logging.info('Model: ' + model.name);
return fixtures.utils.addFixturesForModel(model, localOptions);
Expand Down
20 changes: 2 additions & 18 deletions core/server/data/migrations/init/3-insert-settings.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
var _ = require('lodash'),
models = require('../../../models'),
errors = require('../../../errors'),
versioning = require('../../schema/versioning');
models = require('../../../models');

// @TODO: models.init
module.exports = function insertSettings(options) {
var localOptions = _.merge({context: {internal: true}}, options);

models.init();

return models.Settings.populateDefaults(localOptions)
.then(function () {
return versioning.getDatabaseVersion(localOptions);
})
.catch(function (err) {
if (err instanceof errors.DatabaseVersionError && err.code === 'VERSION_DOES_NOT_EXIST') {
return versioning.setDatabaseVersion(localOptions);
}

throw err;
});
return models.Settings.populateDefaults(localOptions);
};
44 changes: 44 additions & 0 deletions core/server/data/schema/backup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// # Backup Database
// Provides for backing up the database before making potentially destructive changes
var _ = require('lodash'),
fs = require('fs'),
path = require('path'),
Promise = require('bluebird'),
config = require('../../config'),
exporter = require('../export'),

writeExportFile,
backup;

writeExportFile = function writeExportFile(exportResult) {
var filename = path.resolve(config.get('paths').contentPath + '/data/' + exportResult.filename);

return Promise.promisify(fs.writeFile)(filename, JSON.stringify(exportResult.data)).return(filename);
};

/**
* ## Backup
* does an export, and stores this in a local file
*
* @param {{info: logger.info, warn: logger.warn}} [logger]
* @returns {Promise<*>}
*/
backup = function backup(logger) {
// If we get passed a function, use it to output notices, else don't do anything
logger = logger && _.isFunction(logger.info) ? logger : {info: _.noop};

logger.info('Creating database backup');

var props = {
data: exporter.doExport(),
filename: exporter.fileName()
};

return Promise.props(props)
.then(writeExportFile)
.then(function successMessage(filename) {
logger.info('Database backup written to: ' + filename);
});
};

module.exports = backup;
2 changes: 1 addition & 1 deletion core/test/integration/model/model_posts_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ describe('Post Model', function () {
startTags;

// Step 1, fetch a post with its tags, just to see what tags we have
PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
return PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
var post = results.toJSON(toJSONOpts);
should.exist(results);
post.title.should.not.equal('new title');
Expand Down
8 changes: 7 additions & 1 deletion core/test/unit/migration_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@ describe.skip('DB version integrity', function () {
});
});

describe('Migrations', function () {
/**
* we don't use our logic anymore
* so some tests are failing
*
* @TODO: kate-migrations
*/
describe.skip('Migrations', function () {
var loggerStub, resetLogger;

before(function () {
Expand Down
6 changes: 5 additions & 1 deletion core/test/unit/server_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ describe('server bootstrap', function () {
.catch(function (err) {
migration.populate.calledOnce.should.eql(false);
config.get('maintenance').enabled.should.eql(false);
err.code.should.eql('MIGRATION_TABLE_IS_MISSING');

// checking the error code is tricky, because it depends on other tests running before
// it's fine just checking the type of the error
// @TODO: kate-migrations (export errors in knex-migrator to be able to check instanceof)
err.errorType.should.eql('DatabaseIsNotOkError');
done();
});
});
Expand Down
19 changes: 12 additions & 7 deletions core/test/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ var Promise = require('bluebird'),
fs = require('fs-extra'),
path = require('path'),
Module = require('module'),
debug = require('debug')('ghost:test'),
uuid = require('node-uuid'),
KnexMigrator = require('knex-migrator'),
ghost = require('../../server'),
db = require('../../server/data/db'),
migration = require('../../server/data/migration/'),
fixtureUtils = require('../../server/data/migration/fixtures/utils'),
models = require('../../server/models'),
SettingsAPI = require('../../server/api/settings'),
Expand Down Expand Up @@ -405,9 +405,10 @@ initData = function initData() {
return knexMigrator.init();
};

// we must always try to delete all tables
clearData = function clearData() {
// we must always try to delete all tables
return migration.reset();
debug('Database reset');
return knexMigrator.reset();
};

toDoList = {
Expand Down Expand Up @@ -623,12 +624,16 @@ togglePermalinks = function togglePermalinks(request, toggle) {
};

teardown = function teardown(done) {
debug('Database reset');

if (done) {
migration.reset().then(function () {
done();
}).catch(done);
knexMigrator.reset()
.then(function () {
done();
})
.catch(done);
} else {
return migration.reset();
return knexMigrator.reset();
}
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"intl-messageformat": "1.3.0",
"jsonpath": "0.2.7",
"knex": "0.12.5",
"knex-migrator": "0.0.7",
"knex-migrator": "0.2.0",
"lodash": "4.16.6",
"mobiledoc-html-renderer": "0.3.0",
"moment": "2.15.2",
Expand Down

0 comments on commit bae0de6

Please sign in to comment.