From 8f9dc1b86745284d562370226299f70ec1807550 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Thu, 15 May 2014 08:56:00 -0700 Subject: [PATCH] Add support for logical operator (AND/OR) --- lib/connectors/memory.js | 34 ++++++++++++++++++++++------ test/basic-querying.test.js | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index da4bc2c4..ce466221 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -332,14 +332,31 @@ Memory.prototype.all = function all(model, filter, callback) { }; function applyFilter(filter) { - if (typeof filter.where === 'function') { - return filter.where; + var where = filter.where; + if (typeof where === 'function') { + return where; } - var keys = Object.keys(filter.where); + var keys = Object.keys(where); return function (obj) { var pass = true; keys.forEach(function (key) { - if (!test(filter.where[key], obj && obj[key])) { + if(key === 'and' || key === 'or') { + if(Array.isArray(where[key])) { + if(key === 'and') { + pass = where[key].every(function(cond) { + return applyFilter({where: cond})(obj); + }); + return pass; + } + if(key === 'or') { + pass = where[key].some(function(cond) { + return applyFilter({where: cond})(obj); + }); + return pass; + } + } + } + if (!test(where[key], obj && obj[key])) { pass = false; } }); @@ -350,11 +367,14 @@ function applyFilter(filter) { if (typeof value === 'string' && example && example.constructor.name === 'RegExp') { return value.match(example); } - if (typeof example === 'undefined') return undefined; - if (typeof value === 'undefined') return undefined; + if (example === undefined || value === undefined) { + return undefined; + } if (typeof example === 'object') { // ignore geo near filter - if (example.near) return true; + if (example.near) { + return true; + } if (example.inq) { if (!value) return false; diff --git a/test/basic-querying.test.js b/test/basic-querying.test.js index 9b90d66d..ae72ca45 100644 --- a/test/basic-querying.test.js +++ b/test/basic-querying.test.js @@ -131,6 +131,50 @@ describe('basic-querying', function () { }); }); + it('should support "and" operator that is satisfied', function (done) { + User.find({where: {and: [ + {name: 'John Lennon'}, + {role: 'lead'} + ]}}, function (err, users) { + should.not.exist(err); + users.should.have.property('length', 1); + done(); + }); + }); + + it('should support "and" operator that is not satisfied', function (done) { + User.find({where: {and: [ + {name: 'John Lennon'}, + {role: 'member'} + ]}}, function (err, users) { + should.not.exist(err); + users.should.have.property('length', 0); + done(); + }); + }); + + it('should support "or" that is satisfied', function (done) { + User.find({where: {or: [ + {name: 'John Lennon'}, + {role: 'lead'} + ]}}, function (err, users) { + should.not.exist(err); + users.should.have.property('length', 2); + done(); + }); + }); + + it('should support "or" operator that is not satisfied', function (done) { + User.find({where: {or: [ + {name: 'XYZ'}, + {role: 'Hello1'} + ]}}, function (err, users) { + should.not.exist(err); + users.should.have.property('length', 0); + done(); + }); + }); + it('should only include fields as specified', function (done) { var remaining = 0;