| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | 
							- "use strict";
 
- /**
 
-  * Allows components in an aggregation pipeline to report what they need from their input.
 
-  *
 
-  * @class DepsTracker
 
-  * @namespace mungedb-aggregate.pipeline
 
-  * @module mungedb-aggregate
 
-  * @constructor
 
-  */
 
- var DepsTracker = module.exports = function DepsTracker() {
 
- 	// fields is a set of strings
 
- 	this.fields = {};
 
- 	this.needWholeDocument = false;
 
- 	this.needTextScore = false;
 
- }, klass = DepsTracker, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
- var ParsedDeps = require("./ParsedDeps"),
 
- 	Document = require("./Document");
 
- /**
 
-  * Returns a projection object covering the dependencies tracked by this class.
 
-  * @method toProjection
 
-  * @return {Object} projection of caller's dependencies
 
-  */
 
- proto.toProjection = function toProjection() {
 
- 	var proj = {};
 
- 	// if(this.needTextScore) {
 
- 	// 	bb.append(Document::metaFieldTextScore, BSON("$meta" << "textScore"));
 
- 	// }
 
- 	if (this.needWholeDocument) {
 
- 		return proj;
 
- 	}
 
- 	if (Object.keys(this.fields).length === 0) {
 
- 		// Projection language lacks good a way to say no fields needed. This fakes it.
 
- 		proj._id = 0;
 
- 		proj.$noFieldsNeeded = 1;
 
- 		return proj;
 
- 	}
 
- 	var needId = false,
 
- 		last = "";
 
- 	Object.keys(this.fields).sort().forEach(function(it) {
 
- 		if (it.indexOf("_id") === 0 && (it.length === 3 || it[3] === ".")) {
 
- 			// _id and subfields are handled specially due in part to SERVER-7502
 
- 			needId = true;
 
- 			return;
 
- 		}
 
- 		if (last !== "" && it.indexOf(last) === 0) {
 
- 			// we are including a parent of *it so we don't need to include this
 
- 			// field explicitly. In fact, due to SERVER-6527 if we included this
 
- 			// field, the parent wouldn't be fully included. This logic relies
 
- 			// on on set iterators going in lexicographic order so that a string
 
- 			// is always directly before of all fields it prefixes.
 
- 			return;
 
- 		}
 
- 		last = it + ".";
 
- 		proj[it] = 1;
 
- 	});
 
- 	if (needId) // we are explicit either way
 
- 		proj._id = 1;
 
- 	else
 
- 		proj._id = 0;
 
- 	return proj;
 
- };
 
- // ParsedDeps::_fields is a simple recursive look-up table. For each field:
 
- //      If the value has type==Bool, the whole field is needed
 
- //      If the value has type==Object, the fields in the subobject are needed
 
- //      All other fields should be missing which means not needed
 
- /**
 
-  * Takes a depsTracker and builds a simple recursive lookup table out of it.
 
-  * @method toParsedDeps
 
-  * @return {ParsedDeps}
 
-  */
 
- proto.toParsedDeps = function toParsedDeps() {
 
- 	var obj = {};
 
- 	if (this.needWholeDocument || this.needTextScore) {
 
- 		// can't use ParsedDeps in this case
 
- 		return undefined; // TODO: is this equivalent to boost::none ?
 
- 	}
 
- 	var last = "";
 
- 	Object.keys(this.fields).sort().forEach(function (it) {
 
- 		if (last !== "" && it.indexOf(last) === 0) {
 
- 			// we are including a parent of *it so we don't need to include this
 
- 			// field explicitly. In fact, due to SERVER-6527 if we included this
 
- 			// field, the parent wouldn't be fully included. This logic relies
 
- 			// on on set iterators going in lexicographic order so that a string
 
- 			// is always directly before of all fields it prefixes.
 
- 			return;
 
- 		}
 
- 		last = it + ".";
 
- 		Document.setNestedField(obj, it, true);
 
- 	});
 
- 	return new ParsedDeps(obj);
 
- };
 
 
  |