CompareExpression.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. "use strict";
  2. /**
  3. * Generic comparison expression that gets used for $eq, $ne, $lt, $lte, $gt, $gte, and $cmp.
  4. * @class CompareExpression
  5. * @namespace mungedb-aggregate.pipeline.expressions
  6. * @module mungedb-aggregate
  7. * @constructor
  8. **/
  9. var CompareExpression = module.exports = function CompareExpression(cmpOp) {
  10. this.nargs = 2;
  11. this.cmpOp = cmpOp;
  12. base.call(this);
  13. }, klass = CompareExpression,
  14. base = require("./NaryExpression"),
  15. proto = klass.prototype = Object.create(base.prototype, {
  16. constructor: {
  17. value: klass
  18. }
  19. });
  20. // DEPENDENCIES
  21. var Value = require("../Value");
  22. var Expression = require("./Expression");
  23. var ConstantExpression = require("./ConstantExpression");
  24. var FieldPathExpression = require("./FieldPathExpression");
  25. var FieldRangeExpression = require("./FieldRangeExpression");
  26. var NaryExpression = require("./NaryExpression");
  27. // NESTED CLASSES
  28. /**
  29. * Lookup table for truth value returns
  30. *
  31. * @param truthValues truth value for -1, 0, 1
  32. * @param reverse reverse comparison operator
  33. * @param name string name
  34. **/
  35. var CmpLookup = (function() { // emulating a struct
  36. // CONSTRUCTOR
  37. var klass = function CmpLookup(truthValues, reverse, name) {
  38. if (arguments.length !== 3) throw new Error("args expected: truthValues, reverse, name");
  39. this.truthValues = truthValues;
  40. this.reverse = reverse;
  41. this.name = name;
  42. }, base = Object,
  43. proto = klass.prototype = Object.create(base.prototype, {
  44. constructor: {
  45. value: klass
  46. }
  47. });
  48. return klass;
  49. })();
  50. // verify we need this below
  51. // PRIVATE STATIC MEMBERS
  52. /**
  53. * a table of cmp type lookups to truth values
  54. * @private
  55. **/
  56. var cmpLookupMap = [ //NOTE: converted from this Array to a Dict/Object below using CmpLookup#name as the key
  57. // -1 0 1 reverse name (taking advantage of the fact that our 'enums' are strings below)
  58. new CmpLookup([false, true, false], CompareExpression.EQ, CompareExpression.EQ),
  59. new CmpLookup([true, false, true], CompareExpression.NE, CompareExpression.NE),
  60. new CmpLookup([false, false, true], CompareExpression.LT, CompareExpression.GT),
  61. new CmpLookup([false, true, true], CompareExpression.LTE, CompareExpression.GTE),
  62. new CmpLookup([true, false, false], CompareExpression.GT, CompareExpression.LT),
  63. new CmpLookup([true, true, false], CompareExpression.GTE, CompareExpression.LTE),
  64. new CmpLookup([false, false, false], CompareExpression.CMP, CompareExpression.CMP)
  65. ].reduce(function(r, o) {
  66. r[o.name] = o;
  67. return r;
  68. }, {});
  69. klass.parse = function parse(bsonExpr, vps, op) {
  70. var expr = new CompareExpression(op);
  71. var args = NaryExpression.parseArguments(bsonExpr, vps);
  72. expr.validateArguments(args);
  73. expr.vpOperand = args;
  74. return expr;
  75. };
  76. // PROTOTYPE MEMBERS
  77. proto.evaluateInternal = function evaluateInternal(vars) {
  78. //debugger;
  79. var left = this.operands[0].evaluateInternal(vars),
  80. right = this.operands[1].evaluateInternal(vars),
  81. cmp = Expression.signum(Value.compare(left, right));
  82. if (this.cmpOp == Expression.CmpOp.CMP) return cmp;
  83. return cmpLookupMap[this.cmpOp].truthValues[cmp + 1] || false;
  84. };
  85. klass.EQ = "$eq";
  86. klass.NE = "$ne";
  87. klass.GT = "$gt";
  88. klass.GTE = "$gte";
  89. klass.LT = "$lt";
  90. klass.LTE = "$lte";
  91. klass.CMP = "$cmp";
  92. proto.getOpName = function getOpName() {
  93. return this.cmpOp;
  94. };
  95. /** Register Expression */
  96. Expression.registerExpression("$eq", klass.parse);
  97. Expression.registerExpression("$ne", klass.parse);
  98. Expression.registerExpression("$gt", klass.parse);
  99. Expression.registerExpression("$gte", klass.parse);
  100. Expression.registerExpression("$lt", klass.parse);
  101. Expression.registerExpression("$lte", klass.parse);
  102. Expression.registerExpression("$cmp", klass.parse);