Browse Source

EAGLESIX-2706 expression Compare ported to mongo 2.6.5

Jared Hall 11 years ago
parent
commit
58d6aad620
1 changed files with 45 additions and 34 deletions
  1. 45 34
      lib/pipeline/expressions/CompareExpression.js

+ 45 - 34
lib/pipeline/expressions/CompareExpression.js

@@ -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));