diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index 95ed7f3f..9e83b31c 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -295,6 +295,21 @@ Memory.prototype.fromDb = function (model, data) { return data; }; +function getValue(obj, path) { + if (obj == null) { + return undefined; + } + var keys = path.split('.'); + var val = obj; + for (var i = 0, n = keys.length; i < n; i++) { + val = val[keys[i]]; + if (val == null) { + return val; + } + } + return val; +} + Memory.prototype.all = function all(model, filter, callback) { var self = this; var nodes = Object.keys(this.collection(model)).map(function (key) { @@ -361,12 +376,14 @@ Memory.prototype.all = function all(model, filter, callback) { var undefinedA, undefinedB; for (var i = 0, l = this.length; i < l; i++) { - undefinedB = b[this[i].key] === undefined && a[this[i].key] !== undefined; - undefinedA = a[this[i].key] === undefined && b[this[i].key] !== undefined; + var aVal = getValue(a, this[i].key); + var bVal = getValue(b, this[i].key); + undefinedB = bVal === undefined && aVal !== undefined; + undefinedA = aVal === undefined && bVal !== undefined; - if (undefinedB || a[this[i].key] > b[this[i].key]) { + if (undefinedB || aVal > bVal) { return 1 * this[i].reverse; - } else if (undefinedA || a[this[i].key] < b[this[i].key]) { + } else if (undefinedA || aVal < bVal) { return -1 * this[i].reverse; } } @@ -400,7 +417,7 @@ function applyFilter(filter) { } } } - if (!test(where[key], obj && obj[key])) { + if (!test(where[key], getValue(obj, key))) { pass = false; } }); diff --git a/test/memory.test.js b/test/memory.test.js index f3e6ab59..c39b6295 100644 --- a/test/memory.test.js +++ b/test/memory.test.js @@ -146,7 +146,13 @@ describe('Memory connector', function() { birthday: {type: Date, index: true}, role: {type: String, index: true}, order: {type: Number, index: true, sort: true}, - vip: {type: Boolean} + vip: {type: Boolean}, + address: { + street: String, + city: String, + state: String, + zipCode: String + } }); before(seed); @@ -317,6 +323,39 @@ describe('Memory connector', function() { }); }); + it('should support nested property in query', function(done) { + User.find({where: {'address.city': 'San Jose'}}, function(err, users) { + should.not.exist(err); + users.length.should.be.equal(1); + for (var i = 0; i < users.length; i++) { + users[i].address.city.should.be.eql('San Jose'); + } + done(); + }); + }); + + it('should support nested property with gt in query', function(done) { + User.find({where: {'address.city': {gt: 'San'}}}, function(err, users) { + should.not.exist(err); + users.length.should.be.equal(2); + for (var i = 0; i < users.length; i++) { + users[i].address.state.should.be.eql('CA'); + } + done(); + }); + }); + + it('should support nested property for order in query', function(done) { + User.find({where: {'address.state': 'CA'}, order: 'address.city DESC'}, + function(err, users) { + should.not.exist(err); + users.length.should.be.equal(2); + users[0].address.city.should.be.eql('San Mateo'); + users[1].address.city.should.be.eql('San Jose'); + done(); + }); + }); + function seed(done) { var beatles = [ { @@ -325,7 +364,13 @@ describe('Memory connector', function() { email: 'john@b3atl3s.co.uk', role: 'lead', birthday: new Date('1980-12-08'), - vip: true + vip: true, + address: { + street: '123 A St', + city: 'San Jose', + state: 'CA', + zipCode: '95131' + } }, { seq: 1, @@ -334,7 +379,13 @@ describe('Memory connector', function() { role: 'lead', birthday: new Date('1942-06-18'), order: 1, - vip: true + vip: true, + address: { + street: '456 B St', + city: 'San Mateo', + state: 'CA', + zipCode: '94065' + } }, {seq: 2, name: 'George Harrison', order: 5, vip: false}, {seq: 3, name: 'Ringo Starr', order: 6, vip: false},