|
|
@@ -1,8 +1,7 @@
|
|
|
"use strict";
|
|
|
|
|
|
// Autogenerated by cport.py on 2013-09-17 14:37
|
|
|
-var Matcher2 = module.exports = function Matcher2(pattern, nested){
|
|
|
- // File: matcher.cpp lines: 83-92
|
|
|
+var Matcher2 = module.exports = function Matcher2(pattern, whereCallback){
|
|
|
this._pattern = pattern;
|
|
|
this.parser = new MatchExpressionParser();
|
|
|
var result = this.parser.parse(pattern);
|
|
|
@@ -14,243 +13,11 @@ var Matcher2 = module.exports = function Matcher2(pattern, nested){
|
|
|
// DEPENDENCIES
|
|
|
var errors = require("../../Errors.js"),
|
|
|
ErrorCodes = errors.ErrorCodes,
|
|
|
- MatchExpression = require("./MatchExpression.js"),
|
|
|
MatchExpressionParser = require("./MatchExpressionParser.js"),
|
|
|
- FalseMatchExpression = require("./FalseMatchExpression.js"),
|
|
|
- ComparisonMatchExpression = require("./ComparisonMatchExpression.js"),
|
|
|
- InMatchExpression = require("./InMatchExpression.js"),
|
|
|
- AndMatchExpression = require("./AndMatchExpression.js"),
|
|
|
- OrMatchExpression = require("./OrMatchExpression.js"),
|
|
|
- IndexKeyMatchableDocument = require('./IndexKeyMatchableDocument.js'),
|
|
|
- ListOfMatchExpression = require('./ListOfMatchExpression.js'),
|
|
|
- LeafMatchExpression = require("./LeafMatchExpression.js");
|
|
|
|
|
|
-// File: matcher.h lines: 82-82
|
|
|
proto._expression = undefined;
|
|
|
-
|
|
|
-// File: matcher.h lines: 80-80
|
|
|
-proto._indexKey = undefined;
|
|
|
-
|
|
|
-// File: matcher.h lines: 79-79
|
|
|
proto._pattern = undefined;
|
|
|
|
|
|
-// File: matcher.h lines: 84-84
|
|
|
-proto._spliceInfo = undefined;
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * Figure out where our index is
|
|
|
- * @method _spliceForIndex
|
|
|
- * @param keys
|
|
|
- * @param full
|
|
|
- * @param spliceInfo
|
|
|
- *
|
|
|
- */
|
|
|
-proto._spliceForIndex = function _spliceForIndex(keys, full, spliceInfo){
|
|
|
- // File: matcher.cpp lines: 236-380
|
|
|
- var dup, i, obj, lme;
|
|
|
- switch (full) {
|
|
|
- case MatchExpression.ALWAYS_FALSE:
|
|
|
- return new FalseMatchExpression();
|
|
|
-
|
|
|
- case MatchExpression.GEO_NEAR:
|
|
|
- case MatchExpression.NOT:
|
|
|
- case MatchExpression.NOR:
|
|
|
- // maybe?
|
|
|
- return null;
|
|
|
-
|
|
|
- case MatchExpression.OR:
|
|
|
-
|
|
|
- case MatchExpression.AND:
|
|
|
- dup = new ListOfMatchExpression();
|
|
|
- for (i = 0; i < full.numChildren(); i++) {
|
|
|
- var sub = this._spliceForIndex(keys, full.getChild(i), spliceInfo);
|
|
|
- if (!sub)
|
|
|
- continue;
|
|
|
- if (!dup.get()) {
|
|
|
- if (full.matchType() == MatchExpression.AND)
|
|
|
- dup.reset(new AndMatchExpression());
|
|
|
- else
|
|
|
- dup.reset(new OrMatchExpression());
|
|
|
- }
|
|
|
- dup.add(sub);
|
|
|
- }
|
|
|
- if (dup.get()) {
|
|
|
- if (full.matchType() == MatchExpression.OR && dup.numChildren() != full.numChildren()) {
|
|
|
- // TODO: I think this should actuall get a list of all the fields
|
|
|
- // and make sure that's the same
|
|
|
- // with an $or, have to make sure its all or nothing
|
|
|
- return null;
|
|
|
- }
|
|
|
- return dup.release();
|
|
|
- }
|
|
|
- return null;
|
|
|
-
|
|
|
- case MatchExpression.EQ:
|
|
|
- var cmp = new ComparisonMatchExpression(full);
|
|
|
-
|
|
|
- if (cmp.getRHS().type() == Array) {
|
|
|
- // need to convert array to an $in
|
|
|
-
|
|
|
- if (!keys.count(cmp.path().toString()))
|
|
|
- return null;
|
|
|
-
|
|
|
- var newIn = new InMatchExpression();
|
|
|
- newIn.init(cmp.path());
|
|
|
-
|
|
|
- if (newIn.getArrayFilterEntries().addEquality(cmp.getRHS()).isOK())
|
|
|
- return null;
|
|
|
-
|
|
|
- if (cmp.getRHS().Obj().isEmpty())
|
|
|
- newIn.getArrayFilterEntries().addEquality(undefined);
|
|
|
-
|
|
|
- obj = cmp.getRHS().Obj();
|
|
|
- for(i in obj) {
|
|
|
- var s = newIn.getArrayFilterEntries().addEquality( obj[i].next() );
|
|
|
- if (s.code != ErrorCodes.OK)
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- return newIn.release();
|
|
|
- }
|
|
|
- else if (cmp.getRHS().type() === null) {
|
|
|
- //spliceInfo.hasNullEquality = true;
|
|
|
- return null;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case MatchExpression.LTE:
|
|
|
- case MatchExpression.LT:
|
|
|
- case MatchExpression.GT:
|
|
|
- case MatchExpression.GTE:
|
|
|
- cmp = new ComparisonMatchExpression(full);
|
|
|
-
|
|
|
- if ( cmp.getRHS().type() === null) {
|
|
|
- // null and indexes don't play nice
|
|
|
- //spliceInfo.hasNullEquality = true;
|
|
|
- return null;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case MatchExpression.REGEX:
|
|
|
- case MatchExpression.MOD:
|
|
|
- lme = new LeafMatchExpression(full);
|
|
|
- if (!keys.count(lme.path().toString()))
|
|
|
- return null;
|
|
|
- return lme.shallowClone();
|
|
|
-
|
|
|
- case MatchExpression.MATCH_IN:
|
|
|
- lme = new LeafMatchExpression(full);
|
|
|
- if (!keys.count(lme.path().toString()))
|
|
|
- return null;
|
|
|
- var cloned = new InMatchExpression(lme.shallowClone());
|
|
|
- if (cloned.getArrayFilterEntries().hasEmptyArray())
|
|
|
- cloned.getArrayFilterEntries().addEquality(undefined);
|
|
|
-
|
|
|
- // since { $in : [[1]] } matches [1], need to explode
|
|
|
- for (i = cloned.getArrayFilterEntries().equalities().begin(); i != cloned.getArrayFilterEntries().equalities().end(); ++i) {
|
|
|
- var x = cloned[i];
|
|
|
- if (x.type() == Array) {
|
|
|
- for(var j in x) {
|
|
|
- cloned.getArrayFilterEntries().addEquality(x[j]);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return cloned;
|
|
|
-
|
|
|
- case MatchExpression.ALL:
|
|
|
- // TODO: convert to $in
|
|
|
- return null;
|
|
|
-
|
|
|
- case MatchExpression.ELEM_MATCH_OBJECT:
|
|
|
- case MatchExpression.ELEM_MATCH_VALUE:
|
|
|
- // future
|
|
|
- return null;
|
|
|
-
|
|
|
- case MatchExpression.GEO:
|
|
|
- case MatchExpression.SIZE:
|
|
|
- case MatchExpression.EXISTS:
|
|
|
- case MatchExpression.NIN:
|
|
|
- case MatchExpression.TYPE_OPERATOR:
|
|
|
- case MatchExpression.ATOMIC:
|
|
|
- case MatchExpression.WHERE:
|
|
|
- // no go
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * return if our _expression property is atomic or not
|
|
|
- * @method atomic
|
|
|
- *
|
|
|
- */
|
|
|
-proto.atomic = function atomic(){
|
|
|
- // File: matcher.cpp lines: 120-133
|
|
|
- if (!this._expression)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (this._expression.matchType() == MatchExpression.ATOMIC)
|
|
|
- return true;
|
|
|
-
|
|
|
- // we only go down one level
|
|
|
- for (var i = 0; i < this._expression.numChildren(); i++) {
|
|
|
- if (this._expression.getChild(i).matchType() == MatchExpression.ATOMIC)
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * Return the _pattern property
|
|
|
- * @method getQuery
|
|
|
- *
|
|
|
- */
|
|
|
-proto.getQuery = function getQuery(){
|
|
|
- // File: matcher.h lines: 65-64
|
|
|
- return this._pattern;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * Check if we exist
|
|
|
- * @method hasExistsFalse
|
|
|
- *
|
|
|
- */
|
|
|
-proto.hasExistsFalse = function hasExistsFalse(){
|
|
|
- // File: matcher.cpp lines: 172-180
|
|
|
- if (this._spliceInfo.hasNullEquality) {
|
|
|
- // { a : NULL } is very dangerous as it may not got indexed in some cases
|
|
|
- // so we just totally ignore
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return this._isExistsFalse(this._expression.get(), false, this._expression.matchType() == MatchExpression.AND ? -1 : 0);
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * Find if we have a matching key inside us
|
|
|
- * @method keyMatch
|
|
|
- * @param docMatcher
|
|
|
- *
|
|
|
- */
|
|
|
-proto.keyMatch = function keyMatch(docMatcher){
|
|
|
- // File: matcher.cpp lines: 199-206
|
|
|
- if (!this._expression)
|
|
|
- return docMatcher._expression.get() === null;
|
|
|
- if (!docMatcher._expression)
|
|
|
- return false;
|
|
|
- if (this._spliceInfo.hasNullEquality)
|
|
|
- return false;
|
|
|
- return this._expression.equivalent(docMatcher._expression.get());
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
*
|
|
|
* matches checks the input doc against the internal element path to see if it is a match
|
|
|
@@ -260,58 +27,23 @@ proto.keyMatch = function keyMatch(docMatcher){
|
|
|
*
|
|
|
*/
|
|
|
proto.matches = function matches(doc, details){
|
|
|
- // File: matcher.cpp lines: 105-116
|
|
|
if (!this._expression)
|
|
|
return true;
|
|
|
|
|
|
- if (this._indexKey == {})
|
|
|
- return this._expression.matchesBSON(doc, details);
|
|
|
-
|
|
|
if ((doc != {}) && (Object.keys(doc)[0]))
|
|
|
return this._expression.matchesBSON(doc, details);
|
|
|
|
|
|
- var mydoc = new IndexKeyMatchableDocument(this._indexKey, doc);
|
|
|
return this._expression.matches(mydoc, details);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
- * Check if we are a simple match
|
|
|
- * @method singleSimpleCriterion
|
|
|
- *
|
|
|
- */
|
|
|
-proto.singleSimpleCriterion = function singleSimpleCriterion(){
|
|
|
- // File: matcher.cpp lines: 184-196
|
|
|
- if (!this._expression)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (this._expression.matchType() == MatchExpression.EQ)
|
|
|
- return true;
|
|
|
-
|
|
|
- if (this._expression.matchType() == MatchExpression.AND && this._expression.numChildren() == 1 && this._expression.getChild(0).matchType() == MatchExpression.EQ)
|
|
|
- return true;
|
|
|
-
|
|
|
- return false;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * Wrapper around _spliceForIndex
|
|
|
- * @method spliceForIndex
|
|
|
- * @param key
|
|
|
- * @param full
|
|
|
- * @param spliceInfo
|
|
|
+ * Return the _pattern property
|
|
|
+ * @method getQuery
|
|
|
*
|
|
|
*/
|
|
|
-proto.spliceForIndex = function spliceForIndex(key, full, spliceInfo){
|
|
|
- // File: matcher.cpp lines: 209-217
|
|
|
- var keys = [],
|
|
|
- e, i;
|
|
|
- for (i in key) {
|
|
|
- e = key[i];
|
|
|
- keys.insert(e.fieldName());
|
|
|
- }
|
|
|
- return this._spliceForIndex(keys, full, spliceInfo);
|
|
|
+proto.getQuery = function getQuery(){
|
|
|
+ return this._pattern;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
@@ -321,6 +53,5 @@ proto.spliceForIndex = function spliceForIndex(key, full, spliceInfo){
|
|
|
*
|
|
|
*/
|
|
|
proto.toString = function toString(){
|
|
|
- // File: matcher.h lines: 66-65
|
|
|
return this._pattern.toString();
|
|
|
};
|