Skip to content

Commit

Permalink
Data importer improvements and fixes
Browse files Browse the repository at this point in the history
refs #4605, #4479

- Removes versioning from the importer
- Fixes an issue with SQLITE errors not being thrown properly for posts
- Ensures that posts have a created_at date
- Makes sure that the API wrapper is properly handled
  • Loading branch information
ErisDS committed Dec 18, 2014
1 parent 68df133 commit 3c9273e
Show file tree
Hide file tree
Showing 15 changed files with 806 additions and 837 deletions.
8 changes: 0 additions & 8 deletions core/server/data/import/001.js

This file was deleted.

8 changes: 0 additions & 8 deletions core/server/data/import/002.js

This file was deleted.

8 changes: 0 additions & 8 deletions core/server/data/import/003.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,15 @@ var Promise = require('bluebird'),
models = require('../../models'),
utils = require('./utils'),

Importer000;
DataImporter;

Importer000 = function () {
_.bindAll(this, 'doImport');
DataImporter = function () {};

this.version = '000';

this.importFrom = {
'000': this.doImport,
'001': this.doImport,
'002': this.doImport,
'003': this.doImport
};
DataImporter.prototype.importData = function (data) {
return this.doImport(data);
};

Importer000.prototype.importData = function (data) {
return this.canImport(data)
.then(function (importerFunc) {
return importerFunc(data);
});
};

Importer000.prototype.canImport = function (data) {
if (data.meta && data.meta.version && this.importFrom[data.meta.version]) {
return Promise.resolve(this.importFrom[data.meta.version]);
}

return Promise.reject('Unsupported version of data: ' + data.meta.version);
};

Importer000.prototype.loadUsers = function () {
DataImporter.prototype.loadUsers = function () {
var users = {all: {}};

return models.User.findAll({include: ['roles']}).then(function (_users) {
Expand All @@ -52,11 +30,7 @@ Importer000.prototype.loadUsers = function () {
});
};

// Importer000.prototype.importerFunction = function (t) {
//
// };

Importer000.prototype.doUserImport = function (t, tableData, users, errors) {
DataImporter.prototype.doUserImport = function (t, tableData, users, errors) {
var userOps = [],
imported = [];

Expand Down Expand Up @@ -89,7 +63,7 @@ Importer000.prototype.doUserImport = function (t, tableData, users, errors) {
return Promise.resolve({});
};

Importer000.prototype.doImport = function (data) {
DataImporter.prototype.doImport = function (data) {
var self = this,
tableData = data.data,
imported = {},
Expand Down Expand Up @@ -171,8 +145,8 @@ Importer000.prototype.doImport = function (data) {
};

module.exports = {
Importer000: Importer000,
DataImporter: DataImporter,
importData: function (data) {
return new Importer000().importData(data);
return new DataImporter().importData(data);
}
};
25 changes: 6 additions & 19 deletions core/server/data/import/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var Promise = require('bluebird'),
validation = require('../validation'),
errors = require('../../errors'),
uuid = require('node-uuid'),
validator = require('validator'),
importer = require('./data-importer'),
tables = require('../schema').tables,
validate,
handleErrors,
Expand Down Expand Up @@ -89,14 +89,14 @@ sanitize = function sanitize(data) {
});

_.each(tableNames, function (tableName) {
// Sanitize the table data for duplicates and valid uuid values
// Sanitize the table data for duplicates and valid uuid and created_at values
var sanitizedTableData = _.transform(data.data[tableName], function (memo, importValues) {
var uuidMissing = (!importValues.uuid && tables[tableName].uuid) ? true : false,
uuidMalformed = (importValues.uuid && !validator.isUUID(importValues.uuid)) ? true : false,
uuidMalformed = (importValues.uuid && !validation.validator.isUUID(importValues.uuid)) ? true : false,
isDuplicate,
problemTag;

// Check for correct UUID and fix if neccessary
// Check for correct UUID and fix if necessary
if (uuidMissing || uuidMalformed) {
importValues.uuid = uuid.v4();
}
Expand Down Expand Up @@ -184,25 +184,12 @@ validate = function validate(data) {
});
};

module.exports = function (version, data) {
var importer,
sanitizeResults;

sanitizeResults = sanitize(data);
module.exports = function (data) {
var sanitizeResults = sanitize(data);

data = sanitizeResults.data;

return validate(data).then(function () {
try {
importer = require('./' + version);
} catch (ignore) {
// Zero effs given
}

if (!importer) {
return Promise.reject('No importer found');
}

return importer.importData(data);
}).then(function () {
return sanitizeResults;
Expand Down
27 changes: 9 additions & 18 deletions core/server/data/import/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,34 +185,25 @@ utils = {
var ops = [];

tableData = stripProperties(['id'], tableData);

_.each(tableData, function (post) {
// Validate minimum post fields
if (areEmpty(post, 'title', 'slug', 'markdown')) {
return;
}

ops.push(function () {
return models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
// The post importer has auto-timestamping disabled
if (!post.created_at) {
post.created_at = Date.now();
}

ops.push(models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
.catch(function (error) {
return Promise.reject({raw: error, model: 'post', data: post});
});
});
})
);
});

return Promise.reduce(ops, function (results, op) {
return op().then(function (result) {
results.push(result);

return results;
}).catch(function (error) {
if (error) {
results.push(error);
}

return results;
});
}, []).settle();
return Promise.settle(ops);
},

importUsers: function importUsers(tableData, existingUsers, transaction) {
Expand Down
6 changes: 5 additions & 1 deletion core/server/data/importer/handlers/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ JSONHandler = {
importData = JSON.parse(fileData);

// if importData follows JSON-API format `{ db: [exportedData] }`
if (_.keys(importData).length === 1 && Array.isArray(importData.db)) {
if (_.keys(importData).length === 1) {
if (!importData.db || !Array.isArray(importData.db)) {
throw new Error('Invalid JSON format, expected `{ db: [exportedData] }`');
}

importData = importData.db[0];
}

Expand Down
2 changes: 1 addition & 1 deletion core/server/data/importer/importers/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DataImporter = {
return importData;
},
doImport: function (importData) {
return importer('003', importData);
return importer(importData);
}
};

Expand Down
6 changes: 3 additions & 3 deletions core/server/data/validation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ validator.extend('isEmptyOrURL', function (str) {
return (_.isEmpty(str) || validator.isURL(str, {require_protocol: false}));
});

// Validation validation against schema attributes
// values are checked against the validation objects
// form schema.js
// Validation against schema attributes
// values are checked against the validation objects from schema.js
validateSchema = function (tableName, model) {
var columns = _.keys(schema[tableName]),
validationErrors = [];
Expand Down Expand Up @@ -163,6 +162,7 @@ validate = function (value, key, validations) {
};

module.exports = {
validator: validator,
validateSchema: validateSchema,
validateSettings: validateSettings,
validateActiveTheme: validateActiveTheme
Expand Down
Loading

0 comments on commit 3c9273e

Please sign in to comment.