Skip to content

Commit

Permalink
Add support for $regex filter operator
Browse files Browse the repository at this point in the history
  • Loading branch information
erikolson186 committed Oct 19, 2017
1 parent 97cf963 commit 868babf
Show file tree
Hide file tree
Showing 19 changed files with 843 additions and 899 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ global.IDBKeyRange = require('fake-indexeddb/lib/FDBKeyRange');

### Filter Operators

The following filter operators are supported: `$and`, `$or`, `$not`, `$nor`, `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$elemMatch` and `$exists`.
The following filter operators are supported: `$and`, `$or`, `$not`, `$nor`, `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$elemMatch`, `$regex`, and `$exists`.

### Expression Operators

Expand Down
2 changes: 1 addition & 1 deletion build/src/collection.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

Expand Down
2 changes: 1 addition & 1 deletion build/src/create_next_fn.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

Expand Down
2 changes: 1 addition & 1 deletion build/src/db.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

Expand Down
2 changes: 1 addition & 1 deletion build/src/group.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };

Expand Down
42 changes: 42 additions & 0 deletions build/src/lang/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,39 @@ var ElemMatch = function (_Operator5) {
return ElemMatch;
}(Operator);

var RegEx = function (_Operator6) {
_inherits(RegEx, _Operator6);

function RegEx(path, expr) {
_classCallCheck(this, RegEx);

var _this19 = _possibleConstructorReturn(this, Object.getPrototypeOf(RegEx).call(this));

_this19.path = path;
_this19.expr = expr;
return _this19;
}

_createClass(RegEx, [{
key: 'run',
value: function run(fields) {
var value = fields.get(this.path);
if (value === MISSING) {
return false;
}

return this.expr.test(value);
}
}, {
key: 'is_index_matchable',
get: function get() {
return false;
}
}]);

return RegEx;
}(Operator);

var $and = function $and(parent_args, args) {
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
Expand Down Expand Up @@ -995,6 +1028,15 @@ var buildClause = function buildClause(parent_args, path, params) {
op_keys.delete('$elemMatch');
}

if (op_keys.has('$regex')) {
var expr = new RegExp(params.$regex, params.$options);

new_args.push(new RegEx(path, expr));

op_keys.delete('$regex');
op_keys.delete('$options');
}

if (params.$exists && !new_args.length) {
new_args.push(new Exists(path, true));

Expand Down
2 changes: 1 addition & 1 deletion build/src/project.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

Expand Down
2 changes: 1 addition & 1 deletion build/src/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var deepMerge = require('deepmerge'),
clone = require('clone'),
Expand Down
28 changes: 22 additions & 6 deletions build/test/lang/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,33 @@ describe('$elemMatch', function () {
});
});

describe('$regex', function () {
it("shouldn't find clauses for index", function () {
expect(getClauses({ s: { $regex: '' } })).to.have.lengthOf(0);
});

it('should test against a regular expression', function () {
var expr = { s: { $regex: /^[a-z]+$/ } };

expect(evalExpr(expr, { s: 'K' })).to.be.false;
expect(evalExpr(expr, { s: 'k' })).to.be.true;
});

it('should test against a regular expression with options', function () {
var expr = { s: { $regex: /^[a-z]+$/, $options: 'i' } };

expect(evalExpr(expr, { s: 'K' })).to.be.true;
expect(evalExpr(expr, { s: 'k' })).to.be.true;
});
});

describe('$exists', function () {
it('should find clauses for index when exists is true', function () {
expect(getClauses({
x: { $exists: 1 }
})).to.have.lengthOf(1);
expect(getClauses({ x: { $exists: 1 } })).to.have.lengthOf(1);
});

it("shouldn't find clauses for index when exists is false", function () {
expect(getClauses({
x: { $exists: 0 }
})).to.have.lengthOf(0);
expect(getClauses({ x: { $exists: 0 } })).to.have.lengthOf(0);
});

it('should test if document contains a field', function () {
Expand Down
Loading

0 comments on commit 868babf

Please sign in to comment.