Prechádzať zdrojové kódy

Fixes #987. Ported the Accumulator base class. There are no test cases in mongo, since it won't work by itself, so no test cases are included.

http://source.rd.rcg.local/trac/eagle6/changeset/1299/Eagle6_SVN
Spencer Rathbun 12 rokov pred
rodič
commit
85a1f0b1f8
1 zmenil súbory, kde vykonal 78 pridanie a 0 odobranie
  1. 78 0
      lib/pipeline/accumulator/Accumulator.js

+ 78 - 0
lib/pipeline/accumulator/Accumulator.js

@@ -0,0 +1,78 @@
+var Accumulator = module.exports = (function(){
+	// CONSTRUCTOR
+	/** 
+	* A base class for all pipeline accumulators. Uses NaryExpression as a base class.
+	*
+	**/
+	var klass = function Accumulator(){
+		if(arguments.length !== 0) throw new Error("zero args expected");
+		base.call(this);
+	}, base = require("./NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+
+	// DEPENDENCIES
+	// var Value = require("../Value"),
+
+	proto.getFactory = function getFactory(){
+		return klass;	// using the ctor rather than a separate .create() method
+	};
+
+	/**
+	* Adds the operand after checking the current limit
+	* The equal is there because it checks *before* adding the requested argument.
+	* Cannot use checkArgLimit because Accumulator must return a different error code.
+	*
+	* @param expr the operand to add
+	**/
+	proto.addOperand = function addOperand(expr) {
+		if (this.operands.length >= 1) throw new Error("code 15943; group accumulator " + this.getOpName() + " only accepts one operand");
+		base.prototype.addOperand.call(this, expr);
+	};
+
+	/**
+	*   Convenience method for doing this for accumulators.  The pattern
+	*   is always the same, so a common implementation works, but requires
+	*   knowing the operator name.
+	*
+	*   @param {Object} pBuilder the builder to add to
+	*   @param {String} fieldName the projected name
+	*   @param {String} opName the operator name
+	*   @param {Boolean} requireExpression pass down if the expression is needed
+	**/
+	proto.opToBson = function opToBson(pBuilder, opName, fieldName, requireExpression) {
+		if (this.operands.length == 1) throw new Error("this should never happen");
+		var builder = new BSONObjBuilder();
+		this.operands[0].addToBsonObj(builder, opName, requireExpression);
+		pBuilder.append(fieldName, builder.done());
+	};
+
+	/**
+	*   Wrapper around opToBson
+	*
+	*   @param {Object} pBuilder the builder to add to
+	*   @param {String} fieldName the projected name
+	*   @param {Boolean} requireExpression pass down if the expression is needed
+	**/
+	proto.addToBsonObj = function addToBsonObj(pBuilder, fieldName, requireExpression) {
+		this.opToBson(pBuilder, this.getOpName(), fieldName, requireExpression);
+	};
+
+	/**
+	*   Make sure that nobody adds an accumulator to an array
+	*
+	*   @param {Object} pBuilder the builder to add to
+	**/
+	proto.addToBsonArray = function addToBsonArray(pBuilder) {
+		if (false) throw new Error("this should never happen"); // these can't appear in arrays
+	};
+
+	/** 
+	* If this function is not overridden in the sub classes,
+	* then throw an error
+	*
+	**/
+	proto.getValue = function getValue() {
+		throw new Error("You need to define this function on your accumulator");
+	};
+
+	return klass;
+})();