mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Fix export of data during database migration
Closes #2927 -refactor exporter to export tables that exist in the database instead of keying off of schema.js -move some shared database utility functions into their own module
This commit is contained in:
parent
75e2293e91
commit
d9c45b4967
3 changed files with 101 additions and 92 deletions
|
@ -2,15 +2,13 @@ var _ = require('lodash'),
|
|||
when = require('when'),
|
||||
versioning = require('../versioning'),
|
||||
knex = require('../../models/base').knex,
|
||||
schema = require('../schema').tables,
|
||||
utils = require('../utils'),
|
||||
|
||||
excludedTables = ['sessions'],
|
||||
exporter;
|
||||
|
||||
exporter = function () {
|
||||
var tablesToExport = _.keys(schema);
|
||||
|
||||
return when.join(versioning.getDatabaseVersion(), tablesToExport).then(function (results) {
|
||||
return when.join(versioning.getDatabaseVersion(), utils.getTables()).then(function (results) {
|
||||
var version = results[0],
|
||||
tables = results[1],
|
||||
selectOps = _.map(tables, function (name) {
|
||||
|
@ -36,9 +34,9 @@ exporter = function () {
|
|||
|
||||
return when.resolve(exportData);
|
||||
}, function (err) {
|
||||
console.log("Error exporting data: " + err);
|
||||
console.log('Error exporting data: ' + err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = exporter;
|
||||
module.exports = exporter;
|
||||
|
|
|
@ -13,65 +13,21 @@ var _ = require('lodash'),
|
|||
fixtures = require('../fixtures'),
|
||||
schema = require('../schema').tables,
|
||||
dataExport = require('../export'),
|
||||
utils = require('../utils'),
|
||||
|
||||
schemaTables = _.keys(schema),
|
||||
|
||||
init,
|
||||
reset,
|
||||
migrateUp,
|
||||
migrateUpFreshDb,
|
||||
getTables;
|
||||
|
||||
function createTable(table) {
|
||||
return knex.schema.createTable(table, function (t) {
|
||||
var column,
|
||||
columnKeys = _.keys(schema[table]);
|
||||
_.each(columnKeys, function (key) {
|
||||
// creation distinguishes between text with fieldtype, string with maxlength and all others
|
||||
if (schema[table][key].type === 'text' && schema[table][key].hasOwnProperty('fieldtype')) {
|
||||
column = t[schema[table][key].type](key, schema[table][key].fieldtype);
|
||||
} else if (schema[table][key].type === 'string' && schema[table][key].hasOwnProperty('maxlength')) {
|
||||
column = t[schema[table][key].type](key, schema[table][key].maxlength);
|
||||
} else {
|
||||
column = t[schema[table][key].type](key);
|
||||
}
|
||||
|
||||
if (schema[table][key].hasOwnProperty('nullable') && schema[table][key].nullable === true) {
|
||||
column.nullable();
|
||||
} else {
|
||||
column.notNullable();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('primary') && schema[table][key].primary === true) {
|
||||
column.primary();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('unique') && schema[table][key].unique) {
|
||||
column.unique();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('unsigned') && schema[table][key].unsigned) {
|
||||
column.unsigned();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('references') && schema[table][key].hasOwnProperty('inTable')) {
|
||||
//check if table exists?
|
||||
column.references(schema[table][key].references);
|
||||
column.inTable(schema[table][key].inTable);
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('defaultTo')) {
|
||||
column.defaultTo(schema[table][key].defaultTo);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTable(table) {
|
||||
return knex.schema.dropTableIfExists(table);
|
||||
}
|
||||
migrateUpFreshDb;
|
||||
|
||||
function getDeleteCommands(oldTables, newTables) {
|
||||
var deleteTables = _.difference(oldTables, newTables);
|
||||
if (!_.isEmpty(deleteTables)) {
|
||||
return _.map(deleteTables, function (table) {
|
||||
return function () {
|
||||
return deleteTable(table);
|
||||
return utils.deleteTable(table);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -82,34 +38,12 @@ function getAddCommands(oldTables, newTables) {
|
|||
if (!_.isEmpty(addTables)) {
|
||||
return _.map(addTables, function (table) {
|
||||
return function () {
|
||||
return createTable(table);
|
||||
return utils.createTable(table);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getTablesFromSqlite3() {
|
||||
return knex.raw("select * from sqlite_master where type = 'table'").then(function (response) {
|
||||
return _.reject(_.pluck(response[0], 'tbl_name'), function (name) {
|
||||
return name === 'sqlite_sequence';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getTablesFromPgSQL() {
|
||||
return knex.raw("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'").then(function (response) {
|
||||
return _.flatten(_.pluck(response.rows, 'table_name'));
|
||||
});
|
||||
}
|
||||
|
||||
function getTablesFromMySQL() {
|
||||
return knex.raw("show tables").then(function (response) {
|
||||
return _.flatten(_.map(response[0], function (entry) {
|
||||
return _.values(entry);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// Check for whether data is needed to be bootstrapped or not
|
||||
init = function () {
|
||||
var self = this;
|
||||
|
@ -158,7 +92,7 @@ reset = function () {
|
|||
var tables = [];
|
||||
tables = _.map(schemaTables, function (table) {
|
||||
return function () {
|
||||
return deleteTable(table);
|
||||
return utils.deleteTable(table);
|
||||
};
|
||||
}).reverse();
|
||||
|
||||
|
@ -170,7 +104,7 @@ migrateUpFreshDb = function () {
|
|||
var tables = [];
|
||||
tables = _.map(schemaTables, function (table) {
|
||||
return function () {
|
||||
return createTable(table);
|
||||
return utils.createTable(table);
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -211,7 +145,7 @@ function backupDatabase() {
|
|||
// Migrate from a specific version to the latest
|
||||
migrateUp = function () {
|
||||
return backupDatabase().then(function () {
|
||||
return getTables();
|
||||
return utils.getTables();
|
||||
}).then(function (oldTables) {
|
||||
// if tables exist and client is mysqls check if posts table is okay
|
||||
if (!_.isEmpty(oldTables) && client === 'mysql') {
|
||||
|
@ -240,19 +174,6 @@ migrateUp = function () {
|
|||
});
|
||||
};
|
||||
|
||||
getTables = function () {
|
||||
if (client === 'sqlite3') {
|
||||
return getTablesFromSqlite3();
|
||||
}
|
||||
if (client === 'mysql') {
|
||||
return getTablesFromMySQL();
|
||||
}
|
||||
if (client === 'pg') {
|
||||
return getTablesFromPgSQL();
|
||||
}
|
||||
return when.reject("No support for database client " + client);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
init: init,
|
||||
reset: reset,
|
||||
|
|
90
core/server/data/utils/index.js
Normal file
90
core/server/data/utils/index.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
knex = require('../../models/base').knex,
|
||||
schema = require('../schema').tables,
|
||||
client = require('../../models/base').client;
|
||||
|
||||
function createTable(table) {
|
||||
return knex.schema.createTable(table, function (t) {
|
||||
var column,
|
||||
columnKeys = _.keys(schema[table]);
|
||||
_.each(columnKeys, function (key) {
|
||||
// creation distinguishes between text with fieldtype, string with maxlength and all others
|
||||
if (schema[table][key].type === 'text' && schema[table][key].hasOwnProperty('fieldtype')) {
|
||||
column = t[schema[table][key].type](key, schema[table][key].fieldtype);
|
||||
} else if (schema[table][key].type === 'string' && schema[table][key].hasOwnProperty('maxlength')) {
|
||||
column = t[schema[table][key].type](key, schema[table][key].maxlength);
|
||||
} else {
|
||||
column = t[schema[table][key].type](key);
|
||||
}
|
||||
|
||||
if (schema[table][key].hasOwnProperty('nullable') && schema[table][key].nullable === true) {
|
||||
column.nullable();
|
||||
} else {
|
||||
column.notNullable();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('primary') && schema[table][key].primary === true) {
|
||||
column.primary();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('unique') && schema[table][key].unique) {
|
||||
column.unique();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('unsigned') && schema[table][key].unsigned) {
|
||||
column.unsigned();
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('references') && schema[table][key].hasOwnProperty('inTable')) {
|
||||
//check if table exists?
|
||||
column.references(schema[table][key].references);
|
||||
column.inTable(schema[table][key].inTable);
|
||||
}
|
||||
if (schema[table][key].hasOwnProperty('defaultTo')) {
|
||||
column.defaultTo(schema[table][key].defaultTo);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTable(table) {
|
||||
return knex.schema.dropTableIfExists(table);
|
||||
}
|
||||
|
||||
function getTablesFromSqlite3() {
|
||||
return knex.raw("select * from sqlite_master where type = 'table'").then(function (response) {
|
||||
return _.reject(_.pluck(response[0], 'tbl_name'), function (name) {
|
||||
return name === 'sqlite_sequence';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getTablesFromPgSQL() {
|
||||
return knex.raw("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'").then(function (response) {
|
||||
return _.flatten(_.pluck(response.rows, 'table_name'));
|
||||
});
|
||||
}
|
||||
|
||||
function getTablesFromMySQL() {
|
||||
return knex.raw('show tables').then(function (response) {
|
||||
return _.flatten(_.map(response[0], function (entry) {
|
||||
return _.values(entry);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function getTables() {
|
||||
if (client === 'sqlite3') {
|
||||
return getTablesFromSqlite3();
|
||||
}
|
||||
if (client === 'mysql') {
|
||||
return getTablesFromMySQL();
|
||||
}
|
||||
if (client === 'pg') {
|
||||
return getTablesFromPgSQL();
|
||||
}
|
||||
return when.reject("No support for database client " + client);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createTable: createTable,
|
||||
deleteTable: deleteTable,
|
||||
getTables: getTables
|
||||
};
|
Loading…
Add table
Reference in a new issue