| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | 
							- "use strict";
 
- var FieldPathExpression = module.exports = (function(){
 
- 	// CONSTRUCTOR
 
- 	/**
 
- 	 * Create a field path expression. Evaluation will extract the value associated with the given field path from the source document.
 
- 	 *
 
- 	 * @class FieldPathExpression
 
- 	 * @namespace mungedb.aggregate.pipeline.expressions
 
- 	 * @module mungedb-aggregate
 
- 	 * @extends munge.pipeline.expressions.Expression
 
- 	 * @constructor
 
- 	 * @param {String} fieldPath the field path string, without any leading document indicator
 
- 	 **/
 
- 	var klass = function FieldPathExpression(path){
 
- 		if(arguments.length !== 1) throw new Error("args expected: path");
 
- 		this.path = new FieldPath(path);
 
- 	}, base = require("./Expression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
- 	// DEPENDENCIES
 
- 	var FieldPath = require("../FieldPath");
 
- 	// PROTOTYPE MEMBERS
 
- 	proto.evaluate = function evaluate(obj){
 
- 		return this._evaluatePath(obj, 0, this.path.fields.length);
 
- 	};
 
- 	/**
 
- 	 * Internal implementation of evaluate(), used recursively.
 
- 	 *
 
- 	 * The internal implementation doesn't just use a loop because of the
 
- 	 * possibility that we need to skip over an array.  If the path is "a.b.c",
 
- 	 * and a is an array, then we fan out from there, and traverse "b.c" for each
 
- 	 * element of a:[...].  This requires that a be an array of objects in order
 
- 	 * to navigate more deeply.
 
- 	 *
 
- 	 * @param index current path field index to extract
 
- 	 * @param pathLength maximum number of fields on field path
 
- 	 * @param pDocument current document traversed to (not the top-level one)
 
- 	 * @returns the field found; could be an array
 
- 	 **/
 
- 	proto._evaluatePath = function _evaluatePath(obj, i, len){
 
- 		var fieldName = this.path.fields[i],
 
- 			field = obj[fieldName]; // It is possible we won't have an obj (document) and we need to not fail if that is the case
 
- 		// if the field doesn't exist, quit with an undefined value
 
- 		if (field === undefined) return undefined;
 
- 		// if we've hit the end of the path, stop
 
- 		if (++i >= len) return field;
 
- 		// We're diving deeper.  If the value was null, return null
 
- 		if(field === null) return undefined;
 
- 		if (field.constructor === Object) {
 
- 			return this._evaluatePath(field, i, len);
 
- 		} else if (Array.isArray(field)) {
 
- 			var results = [];
 
- 			for (var i2 = 0, l2 = field.length; i2 < l2; i2++) {
 
- 				var subObj = field[i2],
 
- 					subObjType = typeof(subObj);
 
- 				if (subObjType === "undefined" || subObj === null) {
 
- 					results.push(subObj);
 
- 				} else if (subObj.constructor === Object) {
 
- 					results.push(this._evaluatePath(subObj, i, len));
 
- 				} else {
 
- 					throw new Error("the element '" + fieldName + "' along the dotted path '" + this.path.getPath() + "' is not an object, and cannot be navigated.; code 16014");
 
- 				}
 
- 			}
 
- 			return results;
 
- 		}
 
- 		return undefined;
 
- 	};
 
- 	proto.optimize = function(){
 
- 		return this;
 
- 	};
 
- 	proto.addDependencies = function addDependencies(deps){
 
- 		deps[this.path.getPath()] = 1;
 
- 		return deps;
 
- 	};
 
- 	// renamed write to get because there are no streams
 
- 	proto.getFieldPath = function getFieldPath(usePrefix){
 
- 		return this.path.getPath(usePrefix);
 
- 	};
 
- 	proto.toJson = function toJson(){
 
- 		return this.path.getPath(true);
 
- 	};
 
- //TODO: proto.addToBsonObj = ...?
 
- //TODO: proto.addToBsonArray = ...?
 
- //proto.writeFieldPath = ...?   use #getFieldPath instead
 
- 	return klass;
 
- })();
 
 
  |