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 ExclusionNode::excludePath(FieldPath path) { if (path.getPathLength() == 1) { _excludedFields.insert(path.fullPath()); return; } addOrGetChild(path.getFieldName(0))->excludePath(path.tail()); }
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); }
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); }
void run() { FieldPath path = FieldPath("foo.bar.baz").tail(); ASSERT_EQUALS(2U, path.getPathLength()); ASSERT_EQUALS("bar.baz", path.getPath(false)); }