FieldPath.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. "use strict";
  2. var FieldPath = module.exports = FieldPath = (function(){
  3. // CONSTRUCTOR
  4. /**
  5. * Constructor for field paths.
  6. *
  7. * The constructed object will have getPathLength() > 0.
  8. * Uassert if any component field names do not pass validation.
  9. *
  10. * @class FieldPath
  11. * @namespace mungedb.aggregate.pipeline
  12. * @module mungedb-aggregate
  13. * @constructor
  14. * @param fieldPath the dotted field path string or non empty pre-split vector.
  15. **/
  16. var klass = function FieldPath(path){
  17. var fields = typeof(path) === "object" && typeof(path.length) === "number" ? path : path.split(".");
  18. if(fields.length === 0) throw new Error("FieldPath cannot be constructed from an empty vector (String or Array).; code 16409");
  19. for(var i = 0, n = fields.length; i < n; ++i){
  20. var field = fields[i];
  21. if(field.length === 0) throw new Error("FieldPath field names may not be empty strings; code 15998");
  22. if(field[0] == "$") throw new Error("FieldPath field names may not start with '$'; code 16410");
  23. if(field.indexOf("\0") != -1) throw new Error("FieldPath field names may not contain '\\0'; code 16411");
  24. if(field.indexOf(".") != -1) throw new Error("FieldPath field names may not contain '.'; code 16412");
  25. }
  26. this.path = path;
  27. this.fields = fields;
  28. }, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  29. // STATIC MEMBERS
  30. klass.PREFIX = "$";
  31. // PROTOTYPE MEMBERS
  32. /**
  33. * Get the full path.
  34. *
  35. * @method getPath
  36. * @param fieldPrefix whether or not to include the field prefix
  37. * @returns the complete field path
  38. **/
  39. proto.getPath = function getPath(withPrefix) {
  40. return ( !! withPrefix ? FieldPath.PREFIX : "") + this.fields.join(".");
  41. };
  42. /**
  43. * A FieldPath like this but missing the first element (useful for recursion). Precondition getPathLength() > 1.
  44. *
  45. * @method tail
  46. **/
  47. proto.tail = function tail() {
  48. return new FieldPath(this.fields.slice(1));
  49. };
  50. /**
  51. * Get a particular path element from the path.
  52. *
  53. * @method getFieldName
  54. * @param i the zero based index of the path element.
  55. * @returns the path element
  56. **/
  57. proto.getFieldName = function getFieldName(i){ //TODO: eventually replace this with just using .fields[i] directly
  58. return this.fields[i];
  59. };
  60. /**
  61. * Get the number of path elements in the field path.
  62. *
  63. * @method getPathLength
  64. * @returns the number of path elements
  65. **/
  66. proto.getPathLength = function getPathLength() {
  67. return this.fields.length;
  68. };
  69. return klass;
  70. })();