SubstrExpression.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  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}}); //jshint ignore:line
  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")
  22. throw new Error(this.getOpName() + ": starting index must be a numeric type (is JSON type " +
  23. Value.getType(pLower) + "); uassert code 16034");
  24. if (typeof pLength !== "number")
  25. throw new Error(this.getOpName() + ": length must be a numeric type (is JSON type " +
  26. Value.getType(pLength) + "); uassert code 16035");
  27. var lower = Value.coerceToLong(pLower),
  28. length = Value.coerceToLong(pLength);
  29. if (lower >= str.length) {
  30. // If lower > str.length() then string::substr() will throw out_of_range, so return an
  31. // empty string if lower is not a valid string index.
  32. return "";
  33. }
  34. return str.substr(lower, length);
  35. };
  36. Expression.registerExpression("$substr", base.parse);
  37. proto.getOpName = function getOpName() {
  38. return "$substr";
  39. };