diff options
Diffstat (limited to 'src/mongo/db/pipeline/document_source_redact.cpp')
-rw-r--r-- | src/mongo/db/pipeline/document_source_redact.cpp | 211 |
1 files changed, 100 insertions, 111 deletions
diff --git a/src/mongo/db/pipeline/document_source_redact.cpp b/src/mongo/db/pipeline/document_source_redact.cpp index 98916a0afe0..860dd3a8f73 100644 --- a/src/mongo/db/pipeline/document_source_redact.cpp +++ b/src/mongo/db/pipeline/document_source_redact.cpp @@ -39,135 +39,124 @@ namespace mongo { - using boost::intrusive_ptr; - using std::vector; +using boost::intrusive_ptr; +using std::vector; - const char DocumentSourceRedact::redactName[] = "$redact"; +const char DocumentSourceRedact::redactName[] = "$redact"; - DocumentSourceRedact::DocumentSourceRedact(const intrusive_ptr<ExpressionContext>& expCtx, - const intrusive_ptr<Expression>& expression) - : DocumentSource(expCtx) - , _expression(expression) - { } +DocumentSourceRedact::DocumentSourceRedact(const intrusive_ptr<ExpressionContext>& expCtx, + const intrusive_ptr<Expression>& expression) + : DocumentSource(expCtx), _expression(expression) {} - const char *DocumentSourceRedact::getSourceName() const { - return redactName; - } +const char* DocumentSourceRedact::getSourceName() const { + return redactName; +} - static const Value descendVal = Value("descend"); - static const Value pruneVal = Value("prune"); - static const Value keepVal = Value("keep"); +static const Value descendVal = Value("descend"); +static const Value pruneVal = Value("prune"); +static const Value keepVal = Value("keep"); - boost::optional<Document> DocumentSourceRedact::getNext() { - while (boost::optional<Document> in = pSource->getNext()) { - _variables->setRoot(*in); - _variables->setValue(_currentId, Value(*in)); - if (boost::optional<Document> result = redactObject()) { - return result; - } +boost::optional<Document> DocumentSourceRedact::getNext() { + while (boost::optional<Document> in = pSource->getNext()) { + _variables->setRoot(*in); + _variables->setValue(_currentId, Value(*in)); + if (boost::optional<Document> result = redactObject()) { + return result; } - - return boost::none; } - Value DocumentSourceRedact::redactValue(const Value& in) { - const BSONType valueType = in.getType(); - if (valueType == Object) { - _variables->setValue(_currentId, in); - const boost::optional<Document> result = redactObject(); - if (result) { - return Value(*result); - } - else { - return Value(); - } + return boost::none; +} + +Value DocumentSourceRedact::redactValue(const Value& in) { + const BSONType valueType = in.getType(); + if (valueType == Object) { + _variables->setValue(_currentId, in); + const boost::optional<Document> result = redactObject(); + if (result) { + return Value(*result); + } else { + return Value(); } - else if (valueType == Array) { - // TODO dont copy if possible - vector<Value> newArr; - const vector<Value>& arr = in.getArray(); - for (size_t i = 0; i < arr.size(); i++) { - if (arr[i].getType() == Object || arr[i].getType() == Array) { - const Value toAdd = redactValue(arr[i]) ; - if (!toAdd.missing()) { - newArr.push_back(toAdd); - } - } - else { - newArr.push_back(arr[i]); + } else if (valueType == Array) { + // TODO dont copy if possible + vector<Value> newArr; + const vector<Value>& arr = in.getArray(); + for (size_t i = 0; i < arr.size(); i++) { + if (arr[i].getType() == Object || arr[i].getType() == Array) { + const Value toAdd = redactValue(arr[i]); + if (!toAdd.missing()) { + newArr.push_back(toAdd); } + } else { + newArr.push_back(arr[i]); } - return Value(std::move(newArr)); - } - else { - return in; } + return Value(std::move(newArr)); + } else { + return in; } +} - boost::optional<Document> DocumentSourceRedact::redactObject() { - const Value expressionResult = _expression->evaluate(_variables.get()); - - if (expressionResult == keepVal) { - return _variables->getDocument(_currentId); - } - else if (expressionResult == pruneVal) { - return boost::optional<Document>(); - } - else if (expressionResult == descendVal) { - const Document in = _variables->getDocument(_currentId); - MutableDocument out; - out.copyMetaDataFrom(in); - FieldIterator fields(in); - while (fields.more()) { - const Document::FieldPair field(fields.next()); - - // This changes CURRENT so don't read from _variables after this - const Value val = redactValue(field.second); - if (!val.missing()) { - out.addField(field.first, val); - } +boost::optional<Document> DocumentSourceRedact::redactObject() { + const Value expressionResult = _expression->evaluate(_variables.get()); + + if (expressionResult == keepVal) { + return _variables->getDocument(_currentId); + } else if (expressionResult == pruneVal) { + return boost::optional<Document>(); + } else if (expressionResult == descendVal) { + const Document in = _variables->getDocument(_currentId); + MutableDocument out; + out.copyMetaDataFrom(in); + FieldIterator fields(in); + while (fields.more()) { + const Document::FieldPair field(fields.next()); + + // This changes CURRENT so don't read from _variables after this + const Value val = redactValue(field.second); + if (!val.missing()) { + out.addField(field.first, val); } - return out.freeze(); - } - else { - uasserted(17053, str::stream() << "$redact's expression should not return anything " - << "aside from the variables $$KEEP, $$DESCEND, and " - << "$$PRUNE, but returned " - << expressionResult.toString()); } + return out.freeze(); + } else { + uasserted(17053, + str::stream() << "$redact's expression should not return anything " + << "aside from the variables $$KEEP, $$DESCEND, and " + << "$$PRUNE, but returned " << expressionResult.toString()); } +} - intrusive_ptr<DocumentSource> DocumentSourceRedact::optimize() { - _expression = _expression->optimize(); - return this; - } +intrusive_ptr<DocumentSource> DocumentSourceRedact::optimize() { + _expression = _expression->optimize(); + return this; +} - Value DocumentSourceRedact::serialize(bool explain) const { - return Value(DOC(getSourceName() << _expression.get()->serialize(explain))); - } +Value DocumentSourceRedact::serialize(bool explain) const { + return Value(DOC(getSourceName() << _expression.get()->serialize(explain))); +} - intrusive_ptr<DocumentSource> DocumentSourceRedact::createFromBson( - BSONElement elem, - const intrusive_ptr<ExpressionContext>& expCtx) { - - VariablesIdGenerator idGenerator; - VariablesParseState vps(&idGenerator); - Variables::Id currentId = vps.defineVariable("CURRENT"); // will differ from ROOT - Variables::Id decendId = vps.defineVariable("DESCEND"); - Variables::Id pruneId = vps.defineVariable("PRUNE"); - Variables::Id keepId = vps.defineVariable("KEEP"); - intrusive_ptr<Expression> expression = Expression::parseOperand(elem, vps); - intrusive_ptr<DocumentSourceRedact> source = new DocumentSourceRedact(expCtx, expression); - - // TODO figure out how much of this belongs in constructor and how much here. - // Set up variables. Never need to reset DESCEND, PRUNE, or KEEP. - source->_currentId = currentId; - source->_variables.reset(new Variables(idGenerator.getIdCount())); - source->_variables->setValue(decendId, descendVal); - source->_variables->setValue(pruneId, pruneVal); - source->_variables->setValue(keepId, keepVal); - - - return source; - } +intrusive_ptr<DocumentSource> DocumentSourceRedact::createFromBson( + BSONElement elem, const intrusive_ptr<ExpressionContext>& expCtx) { + VariablesIdGenerator idGenerator; + VariablesParseState vps(&idGenerator); + Variables::Id currentId = vps.defineVariable("CURRENT"); // will differ from ROOT + Variables::Id decendId = vps.defineVariable("DESCEND"); + Variables::Id pruneId = vps.defineVariable("PRUNE"); + Variables::Id keepId = vps.defineVariable("KEEP"); + intrusive_ptr<Expression> expression = Expression::parseOperand(elem, vps); + intrusive_ptr<DocumentSourceRedact> source = new DocumentSourceRedact(expCtx, expression); + + // TODO figure out how much of this belongs in constructor and how much here. + // Set up variables. Never need to reset DESCEND, PRUNE, or KEEP. + source->_currentId = currentId; + source->_variables.reset(new Variables(idGenerator.getIdCount())); + source->_variables->setValue(decendId, descendVal); + source->_variables->setValue(pruneId, pruneVal); + source->_variables->setValue(keepId, keepVal); + + + return source; +} } |