FieldPath.js 2.4 KB

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