Accumulator.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. var Accumulator = module.exports = (function(){
  2. // CONSTRUCTOR
  3. /**
  4. * A base class for all pipeline accumulators. Uses NaryExpression as a base class.
  5. *
  6. * @class Accumulator
  7. * @namespace munge.pipeline.accumulators
  8. * @module munge
  9. * @constructor
  10. **/
  11. var klass = function Accumulator(){
  12. if(arguments.length !== 0) throw new Error("zero args expected");
  13. base.call(this);
  14. }, base = require("../expressions/NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  15. // DEPENDENCIES
  16. // var Value = require("../Value"),
  17. proto.getFactory = function getFactory(){
  18. return klass; // using the ctor rather than a separate .create() method
  19. };
  20. /**
  21. * Adds the operand after checking the current limit
  22. * The equal is there because it checks *before* adding the requested argument.
  23. * Cannot use checkArgLimit because Accumulator must return a different error code.
  24. *
  25. * @param expr the operand to add
  26. **/
  27. proto.addOperand = function addOperand(expr) {
  28. if (this.operands.length >= 1) throw new Error("code 15943; group accumulator " + this.getOpName() + " only accepts one operand");
  29. base.prototype.addOperand.call(this, expr);
  30. };
  31. /**
  32. * Convenience method for doing this for accumulators. The pattern
  33. * is always the same, so a common implementation works, but requires
  34. * knowing the operator name.
  35. *
  36. * @param {Object} pBuilder the builder to add to
  37. * @param {String} fieldName the projected name
  38. * @param {String} opName the operator name
  39. * @param {Boolean} requireExpression pass down if the expression is needed
  40. **/
  41. proto.opToBson = function opToBson(pBuilder, opName, fieldName, requireExpression) {
  42. if (this.operands.length == 1) throw new Error("this should never happen");
  43. var builder = new BSONObjBuilder();
  44. this.operands[0].addToBsonObj(builder, opName, requireExpression);
  45. pBuilder.append(fieldName, builder.done());
  46. };
  47. /**
  48. * Wrapper around opToBson
  49. *
  50. * @param {Object} pBuilder the builder to add to
  51. * @param {String} fieldName the projected name
  52. * @param {Boolean} requireExpression pass down if the expression is needed
  53. **/
  54. proto.addToBsonObj = function addToBsonObj(pBuilder, fieldName, requireExpression) {
  55. this.opToBson(pBuilder, this.getOpName(), fieldName, requireExpression);
  56. };
  57. /**
  58. * Make sure that nobody adds an accumulator to an array
  59. *
  60. * @param {Object} pBuilder the builder to add to
  61. **/
  62. proto.addToBsonArray = function addToBsonArray(pBuilder) {
  63. if (false) throw new Error("this should never happen"); // these can't appear in arrays
  64. };
  65. /**
  66. * If this function is not overridden in the sub classes,
  67. * then throw an error
  68. *
  69. **/
  70. proto.getValue = function getValue() {
  71. throw new Error("You need to define this function on your accumulator");
  72. };
  73. return klass;
  74. })();