Accumulator.js 2.7 KB

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