0
Fork 0
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:
Jason Williams 2014-06-09 20:37:44 +00:00
parent 75e2293e91
commit d9c45b4967
3 changed files with 101 additions and 92 deletions

View file

@ -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;

View file

@ -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,

View 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
};