|
|
@@ -8,16 +8,17 @@
|
|
|
* @constructor
|
|
|
**/
|
|
|
var CompareExpression = module.exports = function CompareExpression(cmpOp) {
|
|
|
- this.nargs = 2;
|
|
|
- this.cmpOp = cmpOp;
|
|
|
- base.call(this);
|
|
|
+ if (arguments.length !== 1) throw new Error("one argument expected");
|
|
|
+ this.nargs = 2;
|
|
|
+ this.cmpOp = cmpOp;
|
|
|
+ base.call(this);
|
|
|
}, klass = CompareExpression,
|
|
|
- base = require("./NaryExpression"),
|
|
|
- proto = klass.prototype = Object.create(base.prototype, {
|
|
|
+ base = require("./NaryExpression"),
|
|
|
+ proto = klass.prototype = Object.create(base.prototype, {
|
|
|
constructor: {
|
|
|
value: klass
|
|
|
}
|
|
|
- });
|
|
|
+ });
|
|
|
|
|
|
// DEPENDENCIES
|
|
|
var Value = require("../Value");
|
|
|
@@ -58,37 +59,47 @@ var CmpLookup = (function() { // emulating a struct
|
|
|
* @private
|
|
|
**/
|
|
|
var cmpLookupMap = [ //NOTE: converted from this Array to a Dict/Object below using CmpLookup#name as the key
|
|
|
- // -1 0 1 reverse name (taking advantage of the fact that our 'enums' are strings below)
|
|
|
- new CmpLookup([false, true, false], CompareExpression.EQ, CompareExpression.EQ),
|
|
|
- new CmpLookup([true, false, true], CompareExpression.NE, CompareExpression.NE),
|
|
|
- new CmpLookup([false, false, true], CompareExpression.LT, CompareExpression.GT),
|
|
|
- new CmpLookup([false, true, true], CompareExpression.LTE, CompareExpression.GTE),
|
|
|
- new CmpLookup([true, false, false], CompareExpression.GT, CompareExpression.LT),
|
|
|
- new CmpLookup([true, true, false], CompareExpression.GTE, CompareExpression.LTE),
|
|
|
- new CmpLookup([false, false, false], CompareExpression.CMP, CompareExpression.CMP)
|
|
|
+ // -1 0 1 reverse name (taking advantage of the fact that our 'enums' are strings below)
|
|
|
+ new CmpLookup([false, true, false], CompareExpression.EQ, CompareExpression.EQ),
|
|
|
+ new CmpLookup([true, false, true], CompareExpression.NE, CompareExpression.NE),
|
|
|
+ new CmpLookup([false, false, true], CompareExpression.LT, CompareExpression.GT),
|
|
|
+ new CmpLookup([false, true, true], CompareExpression.LTE, CompareExpression.GTE),
|
|
|
+ new CmpLookup([true, false, false], CompareExpression.GT, CompareExpression.LT),
|
|
|
+ new CmpLookup([true, true, false], CompareExpression.GTE, CompareExpression.LTE),
|
|
|
+
|
|
|
+ // CMP is special. Only name is used.
|
|
|
+ new CmpLookup([false, false, false], CompareExpression.CMP, CompareExpression.CMP)
|
|
|
].reduce(function(r, o) {
|
|
|
r[o.name] = o;
|
|
|
return r;
|
|
|
}, {});
|
|
|
|
|
|
|
|
|
-klass.parse = function parse(bsonExpr, vps, op) {
|
|
|
- var expr = new CompareExpression(op);
|
|
|
- var args = NaryExpression.parseArguments(bsonExpr, vps);
|
|
|
- expr.validateArguments(args);
|
|
|
- expr.vpOperand = args;
|
|
|
- return expr;
|
|
|
-
|
|
|
+//NOTE: DEVIATION FROM MONGO: moving op to the first argument slot so we can bind it
|
|
|
+klass.parse = function parse(op, jsonExpr, vps) {
|
|
|
+ var expr = new CompareExpression(op),
|
|
|
+ args = base.parseArguments(jsonExpr, vps);
|
|
|
+ expr.validateArguments(args);
|
|
|
+ expr.operands = args;
|
|
|
+ return expr;
|
|
|
};
|
|
|
|
|
|
// PROTOTYPE MEMBERS
|
|
|
proto.evaluateInternal = function evaluateInternal(vars) {
|
|
|
- //debugger;
|
|
|
- var left = this.operands[0].evaluateInternal(vars),
|
|
|
- right = this.operands[1].evaluateInternal(vars),
|
|
|
- cmp = Expression.signum(Value.compare(left, right));
|
|
|
- if (this.cmpOp == Expression.CmpOp.CMP) return cmp;
|
|
|
- return cmpLookupMap[this.cmpOp].truthValues[cmp + 1] || false;
|
|
|
+ var left = this.operands[0].evaluateInternal(vars),
|
|
|
+ right = this.operands[1].evaluateInternal(vars),
|
|
|
+ cmp = Value.compare(left, right);
|
|
|
+
|
|
|
+ if(cmp == 0) {
|
|
|
+ //leave as 0
|
|
|
+ } else if(cmp < 0) {
|
|
|
+ cmp = -1;
|
|
|
+ } else if(cmp > 0) {
|
|
|
+ cmp = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.cmpOp === klass.CMP) return cmp;
|
|
|
+ return cmpLookupMap[this.cmpOp].truthValues[cmp + 1];
|
|
|
};
|
|
|
|
|
|
klass.EQ = "$eq";
|
|
|
@@ -104,10 +115,10 @@ proto.getOpName = function getOpName() {
|
|
|
};
|
|
|
|
|
|
/** Register Expression */
|
|
|
-Expression.registerExpression("$eq", klass.parse);
|
|
|
-Expression.registerExpression("$ne", klass.parse);
|
|
|
-Expression.registerExpression("$gt", klass.parse);
|
|
|
-Expression.registerExpression("$gte", klass.parse);
|
|
|
-Expression.registerExpression("$lt", klass.parse);
|
|
|
-Expression.registerExpression("$lte", klass.parse);
|
|
|
-Expression.registerExpression("$cmp", klass.parse);
|
|
|
+Expression.registerExpression("$eq", klass.parse.bind(klass, klass.EQ));
|
|
|
+Expression.registerExpression("$ne", klass.parse.bind(klass, klass.NE));
|
|
|
+Expression.registerExpression("$gt", klass.parse.bind(klass, klass.GT));
|
|
|
+Expression.registerExpression("$gte", klass.parse.bind(klass, klass.GTE));
|
|
|
+Expression.registerExpression("$lt", klass.parse.bind(klass, klass.LT));
|
|
|
+Expression.registerExpression("$lte", klass.parse.bind(klass, klass.LTE));
|
|
|
+Expression.registerExpression("$cmp", klass.parse.bind(klass, klass.CMP));
|