Skip to content

Commit

Permalink
Merge pull request #24 from PlayNetwork/v0.2.16
Browse files Browse the repository at this point in the history
V0.2.16
  • Loading branch information
brozeph committed Mar 8, 2016
2 parents 76f2849 + c9f149a commit 890f020
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 94 deletions.
5 changes: 5 additions & 0 deletions history.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# v0.2.16 / 2016-03-07

* mondern versions of mongoose expect the skip and limit parameter to be an int.
* remove ability to specify gt,gte,lt,lte and ne parameters with an optional filter

# v0.2.15 / 2016-03-04

* Fixed issue where there was an incompatibility with mquery module in mongoose
Expand Down
117 changes: 51 additions & 66 deletions lib/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,79 +38,50 @@ module.exports = function(mongoose) {
return val;
};

var applyGreaterThan = function (spec, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyGreaterThan = function (spec) {
for (var key in spec) {
if (spec.hasOwnProperty(key)) {
(isOptional ? self.or(key) : self.where(key)).gt(spec[key]);
self.where(key).gt(spec[key]);
}
}
};

var applyGreaterThanEqual = function (spec, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyGreaterThanEqual = function (spec) {
for (var key in spec) {
if (spec.hasOwnProperty(key)) {
(isOptional ? self.or(key) : self.where(key)).gte(spec[key]);
self.where(key).gte(spec[key]);
}
}
};

var applyLesserThan = function (spec, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyLesserThan = function (spec) {
for (var key in spec) {
if (spec.hasOwnProperty(key)) {
(isOptional ? self.or(key) : self.where(key)).lt(spec[key]);
self.where(key).lt(spec[key]);
}
}
};

var applyLesserThanEqual = function (spec, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyLesserThanEqual = function (spec) {
for (var key in spec) {
if (spec.hasOwnProperty(key)) {
(isOptional ? self.or(key) : self.where(key)).lte(spec[key]);
self.where(key).lte(spec[key]);
}
}
};

var applyNotEqual = function (spec, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyNotEqual = function (spec) {
for (var key in spec) {
if (spec.hasOwnProperty(key)) {
(isOptional ? self.or(key) : self.where(key))
.ne(analyzeWhereSpec(spec[key]));
self.where(key).ne(analyzeWhereSpec(spec[key]));
}
}
};

var applyRegex = function (spec, buildRegex, isOptional) {
if (typeof isOptional === 'undefined') {
isOptional = false;
}

var applyRegex = function (spec, buildRegex) {
var bulkApply = function (key, val) {
val.forEach(function (term) {
if (isOptional) {
self.or(key, term);
} else {
self.where(key, term);
}
self.where(key, term);
});
};

Expand All @@ -121,14 +92,44 @@ module.exports = function(mongoose) {
if (Array.isArray(val)) {
bulkApply(key, val);
} else {
if (isOptional) {
self.or(key, val);
} else {
self.where(key, val);
}
self.where(key, val);
}
}
}
},
// mongoose.Query.prototype.or handles or clauses differently than
// before. time was you could pass in a key value pair, now it looks
// like it expects array of objects
applyRegexAsOptional = function (spec, buildRegex) {
function bulkApply(key, val) {
var node = {},
nodeOptions = [];

val.forEach(function (term) {
node = {};
node[key] = term;
nodeOptions.push(node);
});

return nodeOptions;
}
var orOptions = [],
orOptionsNode = {};

for (var key in spec) {
if (spec.hasOwnProperty(key)) {
var val = buildRegex(spec[key]);

if (Array.isArray(val)) {
orOptions = orOptions.concat(bulkApply(key, val));
} else {
orOptionsNode = {};
orOptionsNode[key] = val;
orOptions.push(orOptionsNode);
}
}
}
self.or(orOptions);
};

var regexContains = function (val) {
Expand Down Expand Up @@ -199,26 +200,10 @@ module.exports = function(mongoose) {
mandatory.notEqual || mandatory.notEqualTo || mandatory.ne || {});

// OPTIONAL
applyRegex(optional.contains, regexContains, true);
applyRegex(optional.endsWith, regexEndsWith, true);
applyRegex(optional.startsWith, regexStartsWith, true);
applyRegex(optional.exact, regexExact, true);

applyGreaterThan(
optional.greaterThan || optional.gt || {},
true);
applyGreaterThanEqual(
optional.greaterThanEqual || optional.gte || {},
true);
applyLesserThan(
optional.lessThan || optional.lt || {},
true);
applyLesserThanEqual(
optional.lessThanEqual || optional.lte || {},
true);
applyNotEqual(
optional.notEqual || optional.notEqualTo || optional.ne || {},
true);
applyRegexAsOptional(optional.contains, regexContains);
applyRegexAsOptional(optional.endsWith, regexEndsWith);
applyRegexAsOptional(optional.startsWith, regexStartsWith);
applyRegexAsOptional(optional.exact, regexExact);

return self;
};
Expand Down
5 changes: 3 additions & 2 deletions lib/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ module.exports = function(mongoose) {
wrap = {};

options = options || defaults;
options.start = (options && options.start ? options.start : defaults.start);
options.count = (options && options.count ? options.count : defaults.count);
// this might be getting a little long;
options.start = (options && options.start && parseInt(options.start, 10) ? parseInt(options.start, 10) : defaults.start);
options.count = (options && options.count && parseInt(options.count, 10) ? parseInt(options.count, 10) : defaults.count);

if (maxDocs > 0 && (options.count > maxDocs || options.count === 0)) {
options.count = maxDocs;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mongoose-middleware",
"description": "Middleware for mongoose that makes filtering, sorting, pagination and projection chainable and simple to apply",
"version": "0.2.15",
"version": "0.2.16",
"scripts": {
"test": "gulp test-all"
},
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,14 @@ KittehModel

Filters can be used in three ways: mandatory, optional and keyword searches. Additionally, for mandatory and optional searches, exact, contains and startsWith string pattern matches may be used.

The following filters can be used for *mandatory*, *optional*, and *keyword* searches.

* `exact` - Matches the string letter for letter, but is not case sensitive
* `contains` - Matches documents where the string exists as a substring of the field (similar to a where field like '%term%' query in a relational datastore)
* `startsWith` - Matches documents where field begins with the string supplied (similar to a where field like 'term%' query in a relational datastore)
* `endsWith` - Matches documents where field ends with the string supplied (similar to a where field like '%term' query in a relational datastore)

The following filters can *ONLY* be used for *mandatory* and *keyword* searches.
* `greaterThan` (or `gt`) - Matches documents where field value is greater than supplied number or Date value in query
* `greaterThanEqual` (or `gte`) - Matches documents where field value is greater than or equal to supplied number or Date value in query
* `lessThan` (or `lt`) - Matches documents where field value is less than supplied number or Date value in query
Expand Down
60 changes: 35 additions & 25 deletions test/lib/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,48 @@ describe('filter', function () {
before(function () {
filterLib = require('../../lib/filter')(mongoose);

mongoose.Query.prototype.or = function (key, val) {
if (typeof val === 'undefined') {
val = { expr : '', val : null };
}

if (orClause[key]) {
var newVal = [orClause[key], val];
orClause[key] = newVal;
} else {
orClause[key] = val;
mongoose.Query.prototype.or = function (orOptions) {

if (Array.isArray(orOptions)) {
orOptions.forEach(function (elem) {
for (var x in elem) {
if (elem.hasOwnProperty(x)) {
if (orClause[x]) {
var newVal = [orClause[x], elem[x]];
orClause[x] = newVal;
} else {
orClause[x] = elem[x];
}
}
}
});
}

// it doesn't seem the mquery/mongoose supports subsequent gt,lt,
// gte,lte,ne filtering for or queries, however prior to v0.2.16 of
// mongoose-middleware some features were built as though it was
// supported. this will give us some indication if any code remains
// that tries to use these filtering options
return {
gt : function (v) {
orClause[key].expr = 'gt';
orClause[key].val = v;
gt : function () {
throw new Error(
'mongoose.Query.prototype.or does not support gt');
},
gte : function (v) {
orClause[key].expr = 'gte';
orClause[key].val = v;
gte : function () {
throw new Error(
'mongoose.Query.prototype.or does not support gte');
},
lt : function (v) {
orClause[key].expr = 'lt';
orClause[key].val = v;
lt : function () {
throw new Error(
'mongoose.Query.prototype.or does not support lt');
},
lte : function (v) {
orClause[key].expr = 'lte';
orClause[key].val = v;
lte : function () {
throw new Error(
'mongoose.Query.prototype.or does not support lte');
},
ne : function (v) {
orClause[key].expr = 'ne';
orClause[key].val = v;
ne : function () {
throw new Error(
'mongoose.Query.prototype.or does not support ne');
}
};
};
Expand Down
74 changes: 74 additions & 0 deletions test/lib/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,78 @@ describe('page', function () {
return done();
});
});

it('should return results when start is a string', function (done) {
var options = {
start : "0",
count : 100
};

pageLib.initialize({ maxDocs: 50 });

Kitteh
.find()
.page(options, function (err, data) {
should.not.exist(err);
should.exist(data);

return done();
});
});

it('should return results when start is NaN', function (done) {
var options = {
start : "start",
count : 100
};

pageLib.initialize({ maxDocs: 50 });

Kitteh
.find()
.page(options, function (err, data) {
should.not.exist(err);
should.exist(data);

return done();
});
});

it('should return results when count is a string', function (done) {
var options = {
start : 0,
count : "100"
};

pageLib.initialize({ maxDocs: 50 });

Kitteh
.find()
.page(options, function (err, data) {
should.not.exist(err);
should.exist(data);

return done();
});
});

it('should return results when count is NaN', function (done) {
var options = {
start : 0,
count : "count"
};

pageLib.initialize({ maxDocs: 50 });

Kitteh
.find()
.page(options, function (err, data) {
should.not.exist(err);
should.exist(data);

data.options.count.should.equals(50);

return done();
});
});
});

0 comments on commit 890f020

Please sign in to comment.