From 30a54625f27e76bc4b90ef519011585e7e3bd103 Mon Sep 17 00:00:00 2001 From: Rockafella <eugene.kostrikov@gmail.com> Date: Fri, 6 Jun 2014 15:32:04 +0400 Subject: [PATCH] Extended filters --- lib/adapters/mongodb.js | 26 +++++- test/app.js | 1 + test/fixtures.json | 3 + test/fortune-mongodb/mongodb.spec.js | 119 ++++++++++++++++++++++++++- 4 files changed, 145 insertions(+), 4 deletions(-) diff --git a/lib/adapters/mongodb.js b/lib/adapters/mongodb.js index f2f255351..7efc6aef3 100644 --- a/lib/adapters/mongodb.js +++ b/lib/adapters/mongodb.js @@ -230,9 +230,11 @@ adapter.findMany = function(model, query, projection) { var pk = model.pk || "_id"; + if (_.isObject(query) && !_.isArray(query)){ _.each(query, function(val, key){ var m; if(model.schema.tree[key] === Date && _.isString(val)){ + //Strict date equality m = moment(val); if(m.format("YYYY-MM-DD") === val){ @@ -241,8 +243,30 @@ adapter.findMany = function(model, query, projection) { $lte: moment(val).add("days", 1).format("YYYY-MM-DD") }; } - } + }else if ((model.schema.tree[key] === Date || model.schema.tree[key] === Number) && _.isObject(val)){ + //gt/gte/lt/lte for dates and numbers + query[key] = {}; + if (!_.isUndefined(val.gt)){ + query[key].$gt = val.gt; + } + if (!_.isUndefined(val.gte)){ + query[key].$gte = val.gte; + } + if (!_.isUndefined(val.lt)){ + query[key].$lt = val.lt; + } + if (!_.isUndefined(val.lte)){ + query[key].$lte = val.lte; + } + }else if ((model.schema.tree[key] === String || model.schema.tree[key].type === String) && _.isObject(val)){ + //regex for strings + query[key] = { + $regex: val.regex ? val.regex : '', + $options: val.options ? val.options : '' + }; + } }); + } if(_.isObject(query)){ if(_.isArray(query)) { diff --git a/test/app.js b/test/app.js index c6e204c35..5745e2a15 100644 --- a/test/app.js +++ b/test/app.js @@ -66,6 +66,7 @@ module.exports = function(options, port) { official: String, password: String, appearances: Number, + birthday: Date, email: String, pets: ['pet'], soulmate: {ref: 'person', inverse: 'soulmate', type: String}, diff --git a/test/fixtures.json b/test/fixtures.json index 43c7117bc..5cb0cd0d2 100644 --- a/test/fixtures.json +++ b/test/fixtures.json @@ -3,16 +3,19 @@ { "name": "Dilbert", "appearances": 3457, + "birthday": "1990-01-01", "email": "dilbert@mailbert.com" }, { "name": "Wally", "appearances": 1934, + "birthday": "1995-01-01", "email": "wally@mailbert.com" }, { "name": "Robert", "appearances": 0, + "birthday": "2000-01-01", "email": "robert@mailbert.com" } ], diff --git a/test/fortune-mongodb/mongodb.spec.js b/test/fortune-mongodb/mongodb.spec.js index e18674f46..f43283011 100644 --- a/test/fortune-mongodb/mongodb.spec.js +++ b/test/fortune-mongodb/mongodb.spec.js @@ -11,7 +11,7 @@ RSVP.on('error', function(err){ }); module.exports = function(options){ - describe('MongoDB adapter', function(){ + describe.only('MongoDB adapter', function(){ var ids; beforeEach(function(){ @@ -115,7 +115,7 @@ module.exports = function(options){ //hooks add their black magic here. //See what you have in fixtures + what beforeWrite hooks assign in addiction var keys = Object.keys(docs[0]).length; - (keys).should.equal(6); + (keys).should.equal(7); done(); }); }); @@ -172,7 +172,7 @@ module.exports = function(options){ .then(function(doc){ //hooks add their black magic here. //See what you have in fixtures + what beforeWrite hooks assign in addiction - (Object.keys(doc).length).should.equal(6); + (Object.keys(doc).length).should.equal(7); done(); }); }); @@ -192,6 +192,119 @@ module.exports = function(options){ }); }); }); + describe('Filtering', function(){ + it('should be able to filter date by exact value', function(done){ + adapter.findMany('person', {birthday: '2000-01-01'}) + .then(function(docs){ + (docs.length).should.equal(1); + (docs[0].name).should.equal('Robert'); + done(); + }); + }); + it('should be able to filter date range: exclusive', function(done){ + var query = { + birthday: { + lt: '2000-02-02', + gt: '1990-01-01' + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(2); + done(); + }); + }); + it('should be able to filter date range: inclusive', function(done){ + var query = { + birthday: { + gte: '1995-01-01', + lte: '2000-01-01' + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(2); + done(); + }); + }); + it('should be able to filter number range: exclusive', function(done){ + var query = { + appearances: { + gt: 1934, + lt: 4000 + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(1); + done(); + }); + }); + it('should be able to filter number range: inclusive', function(done){ + var query = { + appearances: { + gte: 1934, + lte: 3457 + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(2); + done(); + }); + }); + it('should be able to run regex query with default options', function(done){ + var queryLowercase = { + email: { + regex: 'bert@' + } + }; + var queryUppercase = { + email: { + regex: 'Bert@' + } + }; + new Promise(function(resolve){ + adapter.findMany('person', queryLowercase) + .then(function(docs){ + (docs.length).should.equal(2); + resolve(); + }); + }).then(function(){ + adapter.findMany('person',queryUppercase) + .then(function(docs){ + (docs.length).should.equal(0); + done(); + }); + }); + }); + it('should be possible to specify custom options', function(done){ + var query = { + name: { + regex: 'WALLY', + options: 'i' + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(1); + (docs[0].name).should.equal('Wally'); + done(); + }); + }); + it('should treat empty regex as find all', function(done){ + var query = { + email: { + regex: '' + } + }; + adapter.findMany('person', query) + .then(function(docs){ + (docs.length).should.equal(3); + done(); + }); + }); + }); }); }; \ No newline at end of file