void ExclusionNode::excludePath(FieldPath path) { if (path.getPathLength() == 1) { _excludedFields.insert(path.fullPath()); return; } addOrGetChild(path.getFieldName(0))->excludePath(path.tail()); }
static Value getNestedFieldHelper(const Document& doc, const FieldPath& fieldNames, vector<Position>* positions, size_t level) { fassert(16489, fieldNames.getPathLength()); const string& fieldName = fieldNames.getFieldName(level); const Position pos = doc.positionOf(fieldName); if (!pos.found()) return Value(); if (positions) positions->push_back(pos); if (level == fieldNames.getPathLength()-1) return doc.getField(pos); Value val = doc.getField(pos); if (val.getType() != Object) return Value(); return getNestedFieldHelper(val.getDocument(), fieldNames, positions, level+1); }
void ProjectionNode::addProjectionForPath(const FieldPath& path) { if (path.getPathLength() == 1) { _projectedFields.insert(path.fullPath()); return; } // FieldPath can't be empty, so it is safe to obtain the first path component here. addOrGetChild(path.getFieldName(0).toString())->addProjectionForPath(path.tail()); }
MutableValue MutableDocument::getNestedFieldHelper(const FieldPath& dottedField, size_t level) { if (level == dottedField.getPathLength() - 1) { return getField(dottedField.getFieldName(level)); } else { MutableDocument nested(getField(dottedField.getFieldName(level))); return nested.getNestedFieldHelper(dottedField, level + 1); } }
void ProjectionNode::addExpressionForPath(const FieldPath& path, boost::intrusive_ptr<Expression> expr) { // If the computed fields policy is 'kBanComputedFields', we should never reach here. invariant(_policies.computedFieldsPolicy == ComputedFieldsPolicy::kAllowComputedFields); if (path.getPathLength() == 1) { auto fieldName = path.fullPath(); _expressions[fieldName] = expr; _orderToProcessAdditionsAndChildren.push_back(fieldName); return; } // FieldPath can't be empty, so it is safe to obtain the first path component here. addOrGetChild(path.getFieldName(0).toString())->addExpressionForPath(path.tail(), expr); }
void ProjectionSpecValidator::parseElement(const BSONElement& elem, const FieldPath& pathToElem) { if (elem.type() == BSONType::Object) { parseNestedObject(elem.Obj(), pathToElem); } else { ensurePathDoesNotConflictOrThrow(pathToElem.fullPath()); } }
void DependencyTracker::removeDependency(const FieldPath &rFieldPath) { const size_t nErased = map.erase(rFieldPath); DEV { (log() << "\n---- DependencyTracker::removeDependency(" << rFieldPath.getPath(false) << ") -> " << nErased << "\n").flush(); } }
void DependencyTracker::reportUnsatisfied( const FieldPath &rPath, const DocumentSource *pNeeds, const DocumentSource *pExcludes) { uassert(15984, str::stream() << "unable to satisfy dependency on " << rPath.getPath(true) << " in pipeline[" << pNeeds->getPipelineStep() << "]." << pNeeds->getSourceName() << ", because pipeline[" << pExcludes->getPipelineStep() << "]." << pExcludes->getSourceName() << "] doesn't include it", false); // printf() is way easier to read than this crap }
void ProjectionSpecValidator::parseNestedObject(const BSONObj& thisLevelSpec, const FieldPath& prefix) { if (thisLevelSpec.isEmpty()) { uasserted( 40180, str::stream() << "an empty object is not a valid value. Found empty object at path " << prefix.fullPath()); } for (auto&& elem : thisLevelSpec) { auto fieldName = elem.fieldNameStringData(); if (fieldName[0] == '$') { // This object is an expression specification like {$add: [...]}. It will be parsed // into an Expression later, but for now, just track that the prefix has been // specified and skip it. if (thisLevelSpec.nFields() != 1) { uasserted(40181, str::stream() << "an expression specification must contain exactly " "one field, the name of the expression. Found " << thisLevelSpec.nFields() << " fields in " << thisLevelSpec.toString() << ", while parsing object " << _rawObj.toString()); } ensurePathDoesNotConflictOrThrow(prefix.fullPath()); continue; } if (fieldName.find('.') != std::string::npos) { uasserted(40183, str::stream() << "cannot use dotted field name '" << fieldName << "' in a sub object: " << _rawObj.toString()); } parseElement(elem, FieldPath::getFullyQualifiedPath(prefix.fullPath(), fieldName)); } }
void DependencyTracker::addDependency( const FieldPath &rFieldPath, const DocumentSource *pSource) { Tracker tracker(rFieldPath, pSource); std::pair<MapType::iterator, bool> p( map.insert(std::pair<FieldPath, Tracker>(rFieldPath, tracker))); /* If there was already an entry, update the dependency to be the more recent source. */ if (!p.second) (*p.first).second.pSource = pSource; DEV { (log() << "\n---- DependencyTracker::addDependency(" << rFieldPath.getPath(false) << ", pipeline[" << pSource->getPipelineStep() << "]." << pSource->getSourceName() << ")").flush(); } }
const Value Document::getNestedField(const FieldPath& fieldNames, vector<Position>* positions) const { fassert(16489, fieldNames.getPathLength()); return getNestedFieldHelper(*this, fieldNames, positions, 0); }
MutableValue MutableDocument::getNestedField(const FieldPath& dottedField) { fassert(16601, dottedField.getPathLength()); return getNestedFieldHelper(dottedField, 0); }
size_t DependencyTracker::Tracker::Hash::operator()( const FieldPath &rFieldPath) const { size_t seed = 0xf0afbeef; rFieldPath.hash_combine(seed); return seed; }
void run() { FieldPath path = FieldPath("foo.bar.baz").tail(); ASSERT_EQUALS(2U, path.getPathLength()); ASSERT_EQUALS("bar.baz", path.getPath(false)); }