diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-18 15:00:08 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-18 19:13:27 -0400 |
commit | aef10829fc71cb41c54df5838e9e7e74d41d122b (patch) | |
tree | 23916345612945a059de6798303f2f597561a1f6 /src/mongo/db/update/array_culling_node.cpp | |
parent | b3ad5d465cd2fec4983ff84be9da2cc06c1dac97 (diff) | |
download | mongo-aef10829fc71cb41c54df5838e9e7e74d41d122b.tar.gz |
SERVER-30401 Simplify UpdateLeafNode::apply interface
We need some simplifiction here because UpdateLeafNode::apply is
responsible for so many things (a list of which is in
modifier_node.h). This change puts most of those things into one
function, so that the various modifier implementations can write a few
small overrides to customize their functionality, rather than
reimplementing all of apply() in each case.
This approach extends the PathCreatingNode approach we took previously
for all the modifiers. The one exception is RenameNode, which we
implement by composing SetNode and UnsetNode.
Diffstat (limited to 'src/mongo/db/update/array_culling_node.cpp')
-rw-r--r-- | src/mongo/db/update/array_culling_node.cpp | 72 |
1 files changed, 15 insertions, 57 deletions
diff --git a/src/mongo/db/update/array_culling_node.cpp b/src/mongo/db/update/array_culling_node.cpp index 166c1b21fa5..41389cdbed9 100644 --- a/src/mongo/db/update/array_culling_node.cpp +++ b/src/mongo/db/update/array_culling_node.cpp @@ -32,24 +32,15 @@ namespace mongo { -UpdateNode::ApplyResult ArrayCullingNode::apply(ApplyParams applyParams) const { - if (!applyParams.pathToCreate->empty()) { - // There were path components we could not traverse. We treat this as a no-op, unless it - // would have been impossible to create those elements, which we check with - // checkViability(). - UpdateLeafNode::checkViability( - applyParams.element, *(applyParams.pathToCreate), *(applyParams.pathTaken)); - - return ApplyResult::noopResult(); - } - - // This operation only applies to arrays +ModifierNode::ModifyResult ArrayCullingNode::updateExistingElement( + mutablebson::Element* element, std::shared_ptr<FieldRef> elementPath) const { + invariant(element->ok()); uassert(ErrorCodes::BadValue, "Cannot apply $pull to a non-array value", - applyParams.element.getType() == mongo::Array); + element->getType() == mongo::Array); size_t numRemoved = 0; - auto cursor = applyParams.element.leftChild(); + auto cursor = element->leftChild(); while (cursor.ok()) { // Make sure to get the next array element now, because if we remove the 'cursor' element, // the rightSibling pointer will be invalidated. @@ -61,51 +52,18 @@ UpdateNode::ApplyResult ArrayCullingNode::apply(ApplyParams applyParams) const { cursor = nextElement; } - if (numRemoved == 0) { - return ApplyResult::noopResult(); // Skip the index check, immutable path check, and - // logging steps. - } - - ApplyResult applyResult; - - // Determine if indexes are affected. - if (!applyParams.indexData || - !applyParams.indexData->mightBeIndexed(applyParams.pathTaken->dottedField())) { - applyResult.indexesAffected = false; - } - - // No need to validate for storage, since we cannot have increased the BSON depth or interfered - // with a DBRef. - - // Ensure we are not changing any immutable paths. - for (const auto& immutablePath : applyParams.immutablePaths) { - uassert(ErrorCodes::ImmutableField, - str::stream() << "Performing an update on the path '" - << applyParams.pathTaken->dottedField() - << "' would modify the immutable field '" - << immutablePath->dottedField() - << "'", - applyParams.pathTaken->commonPrefixSize(*immutablePath) < - std::min(applyParams.pathTaken->numParts(), immutablePath->numParts())); - } - - if (applyParams.logBuilder) { - auto& doc = applyParams.logBuilder->getDocument(); - auto logElement = doc.makeElementArray(applyParams.pathTaken->dottedField()); - - for (auto cursor = applyParams.element.leftChild(); cursor.ok(); - cursor = cursor.rightSibling()) { - dassert(cursor.hasValue()); - - auto copy = doc.makeElementWithNewFieldName(StringData(), cursor.getValue()); - uassert(ErrorCodes::InternalError, "could not create copy element", copy.ok()); - uassertStatusOK(logElement.pushBack(copy)); - } + return (numRemoved == 0) ? ModifyResult::kNoOp : ModifyResult::kNormalUpdate; +} - uassertStatusOK(applyParams.logBuilder->addToSets(logElement)); - } +void ArrayCullingNode::validateUpdate(mutablebson::ConstElement updatedElement, + mutablebson::ConstElement leftSibling, + mutablebson::ConstElement rightSibling, + std::uint32_t recursionLevel, + ModifyResult modifyResult) const { + invariant(modifyResult == ModifyResult::kNormalUpdate); - return applyResult; + // Removing elements from an array cannot increase BSON depth or modify a DBRef, so we can + // override validateUpdate to do nothing. } } // namespace mongo |