SubstrExpression.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. "use strict";
  2. /**
  3. * A $substr pipeline expression.
  4. * @see evaluateInternal
  5. * @class SubstrExpression
  6. * @namespace mungedb-aggregate.pipeline.expressions
  7. * @module mungedb-aggregate
  8. * @constructor
  9. */
  10. var SubstrExpression = module.exports = function SubstrExpression() {
  11. if (arguments.length !== 0) throw new Error(klass.name + ": no args expected");
  12. base.call(this);
  13. }, klass = SubstrExpression, base = require("./FixedArityExpressionT")(klass, 3), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  14. var Value = require("../Value"),
  15. Expression = require("./Expression");
  16. proto.evaluateInternal = function evaluateInternal(vars) {
  17. var string = this.operands[0].evaluateInternal(vars),
  18. pLower = this.operands[1].evaluateInternal(vars),
  19. pLength = this.operands[2].evaluateInternal(vars);
  20. var str = Value.coerceToString(string);
  21. if (typeof pLower !== "number") throw new Error(this.getOpName() + ": starting index must be a numeric type (is type " + Value.getType(pLower) + "); uassert code 16034");
  22. if (typeof pLength !== "number") throw new Error(this.getOpName() + ": length must be a numeric type (is type " + Value.getType(pLength) + "); uassert code 16035");
  23. var lower = Value.coerceToLong(pLower),
  24. length = Value.coerceToLong(pLength);
  25. if (lower >= str.length) {
  26. // If lower > str.length() then string::substr() will throw out_of_range, so return an
  27. // empty string if lower is not a valid string index.
  28. return "";
  29. }
  30. return str.substr(lower, length);
  31. };
  32. Expression.registerExpression("$substr", base.parse);
  33. proto.getOpName = function getOpName() {
  34. return "$substr";
  35. };