diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-10 11:27:04 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-10 11:29:14 -0400 |
commit | 5368ddee0e72af3283e2591f751a5b79925e64d0 (patch) | |
tree | 7b3ebd74c06eb78d500016232e79f70a084b03e4 /src/mongo/db/ops | |
parent | d8eda8b631928bd78e71d06f20f39b6611b908a4 (diff) | |
download | mongo-5368ddee0e72af3283e2591f751a5b79925e64d0.tar.gz |
SERVER-28772 Remove the $pushAll modifier.
The $pushAll modifier was deprecated and is now unsupported. Clients
should switch to the $push modifier with $each to get $pushAll
behavior.
This patch also updates some copyright notices that should have been
updated as part of file renames in bf99c6.
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r-- | src/mongo/db/ops/modifier_push.cpp | 61 | ||||
-rw-r--r-- | src/mongo/db/ops/modifier_push.h | 6 | ||||
-rw-r--r-- | src/mongo/db/ops/modifier_push_test.cpp | 121 |
3 files changed, 10 insertions, 178 deletions
diff --git a/src/mongo/db/ops/modifier_push.cpp b/src/mongo/db/ops/modifier_push.cpp index d09006a983c..acd6232841a 100644 --- a/src/mongo/db/ops/modifier_push.cpp +++ b/src/mongo/db/ops/modifier_push.cpp @@ -83,23 +83,13 @@ bool inEachMode(const BSONElement& modExpr) { return true; } -Status parseEachMode(ModifierPush::ModifierPushMode pushMode, - const BSONElement& modExpr, +Status parseEachMode(const BSONElement& modExpr, BSONElement* eachElem, BSONElement* sliceElem, BSONElement* sortElem, BSONElement* positionElem) { Status status = Status::OK(); - // If in $pushAll mode, all we need is the array. - if (pushMode == ModifierPush::PUSH_ALL) { - if (modExpr.type() != Array) { - return Status(ErrorCodes::BadValue, "$pushAll requires an array"); - } - *eachElem = modExpr; - return Status::OK(); - } - // The $each clause must be an array. *eachElem = modExpr.embeddedObject()[kEach]; if (eachElem->type() != Array) { @@ -179,7 +169,7 @@ struct ModifierPush::PreparedState { size_t actualPosition; }; -ModifierPush::ModifierPush(ModifierPush::ModifierPushMode pushMode) +ModifierPush::ModifierPush() : _fieldRef(), _posDollar(0), _eachMode(false), @@ -189,7 +179,6 @@ ModifierPush::ModifierPush(ModifierPush::ModifierPushMode pushMode) _sortPresent(false), _position(std::numeric_limits<std::int32_t>::max()), _sort(), - _pushMode(pushMode), _val() {} ModifierPush::~ModifierPush() {} @@ -231,32 +220,13 @@ Status ModifierPush::init(const BSONElement& modExpr, const Options& opts, bool* BSONElement sortElem; BSONElement positionElem; switch (modExpr.type()) { - case Array: - if (_pushMode == PUSH_ALL) { - _eachMode = true; - Status status = parseEachMode( - PUSH_ALL, modExpr, &_eachElem, &sliceElem, &sortElem, &positionElem); - if (!status.isOK()) { - return status; - } - } else { - _val = modExpr; - } - break; - case Object: - if (_pushMode == PUSH_ALL) { - return Status(ErrorCodes::BadValue, - str::stream() << "$pushAll requires an array of values " - "but was given an embedded document."); - } - // If any known clause ($each, $slice, or $sort) is present, we'd assume // we're using the $each variation of push and would parse accodingly. _eachMode = inEachMode(modExpr); if (_eachMode) { - Status status = parseEachMode( - PUSH_NORMAL, modExpr, &_eachElem, &sliceElem, &sortElem, &positionElem); + Status status = + parseEachMode(modExpr, &_eachElem, &sliceElem, &sortElem, &positionElem); if (!status.isOK()) { return status; } @@ -266,23 +236,12 @@ Status ModifierPush::init(const BSONElement& modExpr, const Options& opts, bool* break; default: - if (_pushMode == PUSH_ALL) { - return Status(ErrorCodes::BadValue, - str::stream() << "$pushAll requires an array of values " - "but was given type: " - << typeName(modExpr.type())); - } - _val = modExpr; break; } // Is slice present and correct? if (sliceElem.type() != EOO) { - if (_pushMode == PUSH_ALL) { - return Status(ErrorCodes::BadValue, "cannot use $slice in $pushAll"); - } - if (!sliceElem.isNumber()) { return Status(ErrorCodes::BadValue, str::stream() << "The value for $slice must " @@ -305,10 +264,6 @@ Status ModifierPush::init(const BSONElement& modExpr, const Options& opts, bool* // Is position present and correct? if (positionElem.type() != EOO) { - if (_pushMode == PUSH_ALL) { - return Status(ErrorCodes::BadValue, "cannot use $position in $pushAll"); - } - // Check that $position can be represented by a 32-bit integer. switch (positionElem.type()) { case NumberInt: @@ -343,10 +298,6 @@ Status ModifierPush::init(const BSONElement& modExpr, const Options& opts, bool* // Is sort present and correct? if (sortElem.type() != EOO) { - if (_pushMode == PUSH_ALL) { - return Status(ErrorCodes::BadValue, "cannot use $sort in $pushAll"); - } - if (sortElem.type() != Object && !sortElem.isNumber()) { return Status(ErrorCodes::BadValue, "The $sort is invalid: use 1/-1 to sort the whole element, " @@ -570,7 +521,7 @@ Status ModifierPush::apply() const { // 2. Add new elements to the array either by going over the $each array or by // appending the (old style $push) element. - if (_eachMode || _pushMode == PUSH_ALL) { + if (_eachMode) { BSONObjIterator itEach(_eachElem.embeddedObject()); // When adding more than one element we keep track of the previous one @@ -672,7 +623,7 @@ Status ModifierPush::log(LogBuilder* logBuilder) const { _preparedState->elemFound); } else { // Set only the positional elements appended - if (_eachMode || _pushMode == PUSH_ALL) { + if (_eachMode) { // For each input element log it as a posisional $set BSONObjIterator itEach(_eachElem.embeddedObject()); while (itEach.more()) { diff --git a/src/mongo/db/ops/modifier_push.h b/src/mongo/db/ops/modifier_push.h index 0f472dfa8d3..2173bfb99d6 100644 --- a/src/mongo/db/ops/modifier_push.h +++ b/src/mongo/db/ops/modifier_push.h @@ -45,8 +45,7 @@ class ModifierPush : public ModifierInterface { MONGO_DISALLOW_COPYING(ModifierPush); public: - enum ModifierPushMode { PUSH_NORMAL, PUSH_ALL }; - explicit ModifierPush(ModifierPushMode mode = PUSH_NORMAL); + ModifierPush(); // // Modifier interface implementation @@ -114,9 +113,6 @@ private: PatternElementCmp _sort; - // Whether this mod is supposed to be parsed as a $pushAll. - const ModifierPushMode _pushMode; - // Simple (old style) push value when the $each variation of the command is not // used. The _eachMode flag would be off if we're this mode. BSONElement _val; diff --git a/src/mongo/db/ops/modifier_push_test.cpp b/src/mongo/db/ops/modifier_push_test.cpp index 008bb140933..cd06eb7d7ff 100644 --- a/src/mongo/db/ops/modifier_push_test.cpp +++ b/src/mongo/db/ops/modifier_push_test.cpp @@ -364,52 +364,6 @@ TEST(Init, PushEachWithEmptySort) { } // -// If in $pushAll semantics, do we check the array and that nothing else is there? -// - -TEST(Init, PushAllSimple) { - BSONObj modObj = fromjson("{$pushAll: {x: [0]}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -TEST(Init, PushAllMultiple) { - BSONObj modObj = fromjson("{$pushAll: {x: [1,2,3]}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -TEST(Init, PushAllObject) { - BSONObj modObj = fromjson("{$pushAll: {x: [{a:1},{a:2}]}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -TEST(Init, PushAllMixed) { - BSONObj modObj = fromjson("{$pushAll: {x: [1,{a:2}]}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -TEST(Init, PushAllWrongType) { - BSONObj modObj = fromjson("{$pushAll: {x: 1}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_NOT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -TEST(Init, PushAllNotArray) { - BSONObj modObj = fromjson("{$pushAll: {x: {a:1}}}"); - ModifierPush mod(ModifierPush::PUSH_ALL); - ASSERT_NOT_OK(mod.init(modObj["$pushAll"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); -} - -// // Are all clauses present? Is anything extroneous? Is anything duplicated? // @@ -481,16 +435,14 @@ TEST(Init, PushEachWithSortFirst) { // Simple mod // -/** Helper to build and manipulate a $push or a $pushAll mod. */ +/** Helper to build and manipulate a $push mod. */ class Mod { public: Mod() : _mod() {} explicit Mod(BSONObj modObj, ModifierInterface::Options options = ModifierInterface::Options::normal()) - : _mod(mongoutils::str::equals(modObj.firstElement().fieldName(), "$pushAll") - ? ModifierPush::PUSH_ALL - : ModifierPush::PUSH_NORMAL) { + : _mod() { _modObj = modObj; StringData modName = modObj.firstElement().fieldName(); ASSERT_OK(_mod.init(_modObj[modName].embeddedObject().firstElement(), options)); @@ -698,73 +650,6 @@ TEST(SimpleObjMod, PrepareApplyDotted) { // -// $pushAll Variation -// - -TEST(PushAll, PrepareApplyEmpty) { - Document doc(fromjson("{a: []}")); - Mod pushMod(fromjson("{$pushAll: {a: [1]}}")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(pushMod.prepare(doc.root(), "", &execInfo)); - - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); - - ASSERT_OK(pushMod.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(doc, fromjson("{a: [1]}")); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(pushMod.log(&logBuilder)); - ASSERT_EQUALS(countChildren(logDoc.root()), 1u); - ASSERT_EQUALS(logDoc, fromjson("{$set: {a: [1]}}")); -} - -TEST(PushAll, PrepareApplyInexistent) { - Document doc(fromjson("{}")); - Mod pushMod(fromjson("{$pushAll: {a: [1]}}")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(pushMod.prepare(doc.root(), "", &execInfo)); - - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); - - ASSERT_OK(pushMod.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(doc, fromjson("{a: [1]}")); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(pushMod.log(&logBuilder)); - ASSERT_EQUALS(countChildren(logDoc.root()), 1u); - ASSERT_EQUALS(logDoc, fromjson("{$set: {a: [1]}}")); -} - -TEST(PushAll, PrepareApplyNormal) { - Document doc(fromjson("{a: [0]}")); - Mod pushMod(fromjson("{$pushAll: {a: [1,2]}}")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(pushMod.prepare(doc.root(), "", &execInfo)); - - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); - - ASSERT_OK(pushMod.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(doc, fromjson("{a: [0,1,2]}")); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(pushMod.log(&logBuilder)); - ASSERT_EQUALS(countChildren(logDoc.root()), 1u); - ASSERT_EQUALS(logDoc, fromjson("{$set: {'a.1': 1, 'a.2':2}}")); -} - -// // Simple $each mod // @@ -1321,7 +1206,7 @@ TEST(ToPosition, BadInputs) { int i = 0; while (bad[i] != NULL) { - ModifierPush pushMod(ModifierPush::PUSH_NORMAL); + ModifierPush pushMod; BSONObj modObj = fromjson(bad[i]); ASSERT_NOT_OK(pushMod.init(modObj.firstElement().embeddedObject().firstElement(), ModifierInterface::Options::normal())); |