-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved knex-migrator execution into Ghost
refs #9742, refs TryGhost/Ghost-CLI#759 - required a reordering of Ghost's bootstrap file, because: - we have to ensure that no database queries are executed within Ghost during the migrations - make 3 sections: check if db needs initialisation, bootstrap Ghost with minimal components (db/models, express apps, load settings+theme) - create a new `migrator` utility, which tells you which state your db is in and offers an API to execute knex-migrator based on this state - ensure we still detect an incompatible db: you connect your 2.0 blog with a 0.11 database - enable maintenance mode if migrations are missing - if the migration have failed, knex-migrator roll auto rollback - you can automatically switch to 1.0 again - added socket communication for the CLI
- Loading branch information
Showing
10 changed files
with
304 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
const KnexMigrator = require('knex-migrator'), | ||
config = require('../../config'), | ||
common = require('../../lib/common'), | ||
knexMigrator = new KnexMigrator({ | ||
knexMigratorFilePath: config.get('paths:appRoot') | ||
}); | ||
|
||
module.exports.getState = () => { | ||
let state, err; | ||
|
||
return knexMigrator.isDatabaseOK() | ||
.then(() => { | ||
state = 1; | ||
return state; | ||
}) | ||
.catch((_err) => { | ||
err = _err; | ||
|
||
// CASE: database was never created | ||
if (err.code === 'DB_NOT_INITIALISED') { | ||
state = 2; | ||
return state; | ||
} | ||
|
||
// CASE: you have created the database on your own, you have an existing none compatible db? | ||
if (err.code === 'MIGRATION_TABLE_IS_MISSING') { | ||
state = 3; | ||
return state; | ||
} | ||
|
||
// CASE: database needs migrations | ||
if (err.code === 'DB_NEEDS_MIGRATION') { | ||
state = 4; | ||
return state; | ||
} | ||
|
||
// CASE: database connection errors, unknown cases | ||
throw err; | ||
}); | ||
}; | ||
|
||
module.exports.dbInit = () => { | ||
return knexMigrator.init(); | ||
}; | ||
|
||
module.exports.migrate = () => { | ||
return knexMigrator.migrate(); | ||
}; | ||
|
||
module.exports.isDbCompatible = (connection) => { | ||
return connection.raw('SELECT `key` FROM settings WHERE `key`="databaseVersion";') | ||
.then((response) => { | ||
if (!response || !response[0].length) { | ||
return; | ||
} | ||
|
||
throw new common.errors.DatabaseVersionError({ | ||
message: 'Your database version is not compatible with Ghost 2.0.', | ||
help: 'Want to keep your DB? Use Ghost < 1.0.0 or the "0.11" branch.' + | ||
'\n\n\n' + | ||
'Want to migrate Ghost 0.11 to 2.0? Please visit https://docs.ghost.org/v1/docs/migrating-to-ghost-1-0-0' | ||
}); | ||
}) | ||
.catch((err) => { | ||
// CASE settings table doesn't exists | ||
if (err.errno === 1146 || err.errno === 1) { | ||
return; | ||
} | ||
|
||
throw err; | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,20 @@ | ||
var _ = require('lodash'), | ||
config = require('../../../../config'), | ||
const _ = require('lodash'), | ||
database = require('../../../db'); | ||
|
||
module.exports = function after() { | ||
// 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; | ||
} | ||
|
||
// running knex-migrator migrate --init does two different migration calls within a single process | ||
// we have to ensure that we clear the Ghost cache afterwards, otherwise we operate on a destroyed connection | ||
_.each(require.cache, function (val, key) { | ||
if (key.match(/core\/server/)) { | ||
delete require.cache[key]; | ||
} | ||
}); | ||
module.exports = function shutdown(options = {}) { | ||
if (options.executedFromShell === true) { | ||
// running knex-migrator migrate --init in the shell does two different migration calls within a single process | ||
// we have to ensure that we clear the Ghost cache afterwards, otherwise we operate on a destroyed connection | ||
_.each(require.cache, function (val, key) { | ||
if (key.match(/core\/server/)) { | ||
delete require.cache[key]; | ||
} | ||
}); | ||
|
||
// 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(); | ||
/** | ||
* We have to close Ghost's db connection if knex-migrator was used in the shell. | ||
* Otherwise the process doesn't exit. | ||
*/ | ||
return database.knex.destroy(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,11 @@ | ||
var config = require('../../../../config'), | ||
database = require('../../../db'); | ||
const database = require('../../../db'); | ||
|
||
module.exports = function after() { | ||
// 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; | ||
module.exports = function shutdown(options = {}) { | ||
/** | ||
* We have to close Ghost's db connection if knex-migrator was used in the shell. | ||
* Otherwise the process doesn't exit. | ||
*/ | ||
if (options.executedFromShell === true) { | ||
return database.knex.destroy(); | ||
} | ||
|
||
// 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(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.