diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index 29f25166..c43e5093 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -72,7 +72,7 @@ function deserialize(dbObj) { Memory.prototype.getCollection = function(model) { var modelClass = this._models[model]; - if (modelClass.settings.memory) { + if (modelClass && modelClass.settings.memory) { model = modelClass.settings.memory.collection || model; } return model; @@ -614,13 +614,37 @@ Memory.prototype.buildNearFilter = function (filter) { } Memory.prototype.automigrate = function (models, cb) { - if (typeof models === 'function') cb = models, models = []; - if (models.length === 0) models = Object.keys(this._models); var self = this; + + if ((!cb) && ('function' === typeof models)) { + cb = models; + models = undefined; + } + // First argument is a model name + if ('string' === typeof models) { + models = [models]; + } + + models = models || Object.keys(self._models); + if (models.length === 0) { + return process.nextTick(cb); + } + + var invalidModels = models.filter(function(m) { + return !(m in self._models); + }); + + if (invalidModels.length) { + return process.nextTick(function() { + cb(new Error('Cannot migrate models not attached to this datasource: ' + + invalidModels.join(' '))); + }); + } + models.forEach(function(m) { self.initCollection(m); }); - if (cb) cb(); + if (cb) process.nextTick(cb); } function merge(base, update) { diff --git a/lib/datasource.js b/lib/datasource.js index 572c1276..df9437b6 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -759,15 +759,46 @@ DataSource.prototype.defineProperty = function (model, prop, params) { */ DataSource.prototype.automigrate = function (models, cb) { this.freeze(); - if (this.connector.automigrate) { - this.connector.automigrate(models, cb); - } else { - if ((!cb) && ('function' === typeof models)) { - cb = models; - models = undefined; - } - cb && process.nextTick(cb); + + if ((!cb) && ('function' === typeof models)) { + cb = models; + models = undefined; } + + if (!this.connector.automigrate) { + // NOOP + return cb && process.nextTick(cb); + } + + // First argument is a model name + if ('string' === typeof models) { + models = [models]; + } + + var attachedModels = this.connector._models; + + if (attachedModels && typeof attachedModels === 'object') { + models = models || Object.keys(attachedModels); + + if (models.length === 0) { + return cb && process.nextTick(cb); + } + + var invalidModels = models.filter(function(m) { + return !(m in attachedModels); + }); + + if (invalidModels.length) { + return process.nextTick(function() { + if (cb) { + cb(new Error('Cannot migrate models not attached to this datasource: ' + + invalidModels.join(' '))); + } + }); + } + } + + this.connector.automigrate(models, cb); }; /** @@ -777,17 +808,48 @@ DataSource.prototype.automigrate = function (models, cb) { * @param {String} model Model to migrate. If not present, apply to all models. Can also be an array of Strings. * @param {Function} [cb] The callback function */ -DataSource.prototype.autoupdate = function (models, cb) { +DataSource.prototype.autoupdate = function(models, cb) { this.freeze(); - if (this.connector.autoupdate) { - this.connector.autoupdate(models, cb); - } else { - if ((!cb) && ('function' === typeof models)) { - cb = models; - models = undefined; - } - cb && process.nextTick(cb); + + if ((!cb) && ('function' === typeof models)) { + cb = models; + models = undefined; } + + if (!this.connector.autoupdate) { + // NOOP + return cb && process.nextTick(cb); + } + + // First argument is a model name + if ('string' === typeof models) { + models = [models]; + } + + var attachedModels = this.connector._models; + + if (attachedModels && typeof attachedModels === 'object') { + models = models || Object.keys(attachedModels); + + if (models.length === 0) { + return process.nextTick(cb); + } + + var invalidModels = models.filter(function(m) { + return !(m in attachedModels); + }); + + if (invalidModels.length) { + return process.nextTick(function() { + if (cb) { + cb(new Error('Cannot migrate models not attached to this datasource: ' + + invalidModels.join(' '))); + } + }); + } + } + + this.connector.autoupdate(models, cb); }; /** diff --git a/package.json b/package.json index b25460de..6d1cd336 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-datasource-juggler", - "version": "2.10.1", + "version": "2.10.2", "description": "LoopBack DataSoure Juggler", "keywords": [ "StrongLoop", diff --git a/test/memory.test.js b/test/memory.test.js index 66ad2346..f07ab015 100644 --- a/test/memory.test.js +++ b/test/memory.test.js @@ -312,6 +312,44 @@ describe('Memory connector', function () { }); }); + describe('automigrate', function() { + var ds; + beforeEach(function() { + ds = new DataSource({ + connector: 'memory' + }); + + ds.createModel('m1', { + name: String + }); + }); + + it('automigrate all models', function(done) { + ds.automigrate(function(err) { + done(err); + }); + }); + + it('automigrate one model', function(done) { + ds.automigrate('m1', function(err) { + done(err); + }); + }); + + it('automigrate one or more models in an array', function(done) { + ds.automigrate(['m1'], function(err) { + done(err); + }); + }); + + it('automigrate reports errors for models not attached', function(done) { + ds.automigrate(['m1', 'm2'], function(err) { + err.should.be.an.instanceOf(Error); + done(); + }); + }); + }); + });