"use strict"; var LeafMatchExpression = require("./LeafMatchExpression.js"); var Value = require("../Value"); /** * ComparisonMatchExpression * @class ComparisonMatchExpression * @namespace mungedb-aggregate.pipeline.matcher * @module mungedb-aggregate * @constructor */ var ComparisonMatchExpression = module.exports = function ComparisonMatchExpression(type){ base.call(this); this._matchType = type; }, klass = ComparisonMatchExpression, base = LeafMatchExpression, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}}); proto._rhs = undefined; /** * * Writes a debug string for this object * @method debugString * @param level * */ proto.debugString = function debugString(level) { var retStr = this._debugAddSpace(level) + this.path() + " "; switch (this._matchType) { case "LT": retStr += "$lt"; break; case "LTE": retStr += "$lte"; break; case "EQ": retStr += "=="; break; case "GT": retStr += "$gt"; break; case "GTE": retStr += "$gte"; break; default: retStr += "Unknown comparison!"; break; } retStr += (this._rhs ? this._rhs.toString() : "?"); if (this.getTag()) { retStr += this.getTag().debugString(); } return retStr + "\n"; }; /** * * checks if this expression is == to the other * @method equivalent * @param other * */ proto.equivalent = function equivalent(other) { if (other._matchType != this._matchType) return false; return this.path() === other.path() && Value.compare(this._rhs,other._rhs) === 0; }; /** * * Return the _rhs property * @method getData * */ proto.getData = function getData() { return this._rhs; }; /** * * Return the _rhs property * @method getRHS * */ proto.getRHS = function getRHS() { return this._rhs; }; /** * * Initialize the necessary items * @method init * @param path * @param type * */ proto.init = function init(path,rhs) { this._rhs = rhs; if ((rhs instanceof Object && Object.keys(rhs).length === 0)) return {"code":"BAD_VALUE", "description":"Need a real operand"}; if (rhs === undefined) return {"code":"BAD_VALUE", "desc":"Cannot compare to undefined"}; if (!(this._matchType in {"LT":1, "LTE":1, "EQ":1, "GT":1, "GTE":1})) { return {"code":"BAD_VALUE", "description":"Bad match type for ComparisonMatchExpression"}; } return this.initPath(path); }; /** * * Check if the input element matches * @method matchesSingleElement * @param e * */ proto.matchesSingleElement = function matchesSingleElement(e) { if (Value.canonicalize(e) !== Value.canonicalize(this._rhs)) { if (Value.canonicalize(e) + Value.canonicalize(this._rhs) === 5) { return ["EQ","LTE","GTE"].indexOf(this._matchType) != -1; } if (["MaxKey","MinKey"].indexOf(Value.getType(this._rhs)) != -1) { return this._matchType !== "EQ"; } return false; } var x = Value.compare(e, this._rhs); switch(this._matchType) { case "LT": return x < 0; case "LTE": return x <= 0; case "EQ": return x === 0; case "GT": return x > 0; case "GTE": return x >= 0; default: throw new Error("Invalid comparison type evaluated."); } };