summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops/write_ops_parsers.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/ops/write_ops_parsers.h')
-rw-r--r--src/mongo/db/ops/write_ops_parsers.h76
1 files changed, 42 insertions, 34 deletions
diff --git a/src/mongo/db/ops/write_ops_parsers.h b/src/mongo/db/ops/write_ops_parsers.h
index 70eb8d1a7d3..0464a3349df 100644
--- a/src/mongo/db/ops/write_ops_parsers.h
+++ b/src/mongo/db/ops/write_ops_parsers.h
@@ -33,10 +33,12 @@
#include "mongo/bson/bsonelement.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/exec/document_value/value.h"
+#include "mongo/db/update/document_diff_serialization.h"
+#include "mongo/stdx/variant.h"
+#include "mongo/util/visit_helper.h"
namespace mongo {
namespace write_ops {
-
// Conservative per array element overhead. This value was calculated as 1 byte (element type) + 5
// bytes (max string encoding of the array index encoded as string and the maximum key is 99999) + 1
// byte (zero terminator) = 7 bytes
@@ -55,19 +57,24 @@ void writeMultiDeleteProperty(bool isMulti, StringData fieldName, BSONObjBuilder
class UpdateModification {
public:
- enum class Type { kClassic, kPipeline };
+ enum class Type { kClassic, kPipeline, kDelta };
- static StringData typeToString(Type type) {
- return (type == Type::kClassic ? "Classic"_sd : "Pipeline"_sd);
- }
+ /**
+ * Used to indicate that a diff is being passed to the constructor.
+ */
+ struct DiffTag {};
+
+ // Given the 'o' field of an update oplog entry, will return an UpdateModification that can be
+ // applied.
+ static UpdateModification parseFromOplogEntry(const BSONObj& oField);
UpdateModification() = default;
UpdateModification(BSONElement update);
UpdateModification(std::vector<BSONObj> pipeline);
+ UpdateModification(doc_diff::Diff, DiffTag);
// This constructor exists only to provide a fast-path for constructing classic-style updates.
UpdateModification(const BSONObj& update);
-
/**
* These methods support IDL parsing of the "u" field from the update command and OP_UPDATE.
*/
@@ -83,50 +90,51 @@ public:
// representing an aggregation stage, due to the leading '$'' character.
static UpdateModification parseLegacyOpUpdateFromBSON(const BSONObj& obj);
- int objsize() const {
- if (_type == Type::kClassic) {
- return _classicUpdate->objsize();
- }
+ int objsize() const;
- int size = 0;
- std::for_each(_pipeline->begin(), _pipeline->end(), [&size](const BSONObj& obj) {
- size += obj.objsize() + kWriteCommandBSONArrayPerElementOverheadBytes;
- });
-
- return size + kWriteCommandBSONArrayPerElementOverheadBytes;
- }
-
- Type type() const {
- return _type;
- }
+ Type type() const;
BSONObj getUpdateClassic() const {
- invariant(_type == Type::kClassic);
- return *_classicUpdate;
+ invariant(type() == Type::kClassic);
+ return stdx::get<ClassicUpdate>(_update).bson;
}
const std::vector<BSONObj>& getUpdatePipeline() const {
- invariant(_type == Type::kPipeline);
- return *_pipeline;
+ invariant(type() == Type::kPipeline);
+ return stdx::get<PipelineUpdate>(_update);
+ }
+
+ doc_diff::Diff getDiff() const {
+ invariant(type() == Type::kDelta);
+ return stdx::get<doc_diff::Diff>(_update);
}
std::string toString() const {
StringBuilder sb;
- sb << "{type: " << typeToString(_type) << ", update: ";
- if (_type == Type::kClassic) {
- sb << *_classicUpdate << "}";
- } else {
- sb << Value(*_pipeline).toString();
- }
+ stdx::visit(visit_helper::Overloaded{[&sb](const ClassicUpdate& classic) {
+ sb << "{type: Classic, update: " << classic.bson
+ << "}";
+ },
+ [&sb](const PipelineUpdate& pipeline) {
+ sb << "{type: Pipeline, update: "
+ << Value(pipeline).toString() << "}";
+ },
+ [&sb](const doc_diff::Diff& diff) {
+ sb << "{type: Delta, update: " << diff << "}";
+ }},
+ _update);
return sb.str();
}
private:
- Type _type = Type::kClassic;
- boost::optional<BSONObj> _classicUpdate;
- boost::optional<std::vector<BSONObj>> _pipeline;
+ // Wrapper class used to avoid having a variant where multiple alternatives have the same type.
+ struct ClassicUpdate {
+ BSONObj bson;
+ };
+ using PipelineUpdate = std::vector<BSONObj>;
+ stdx::variant<ClassicUpdate, PipelineUpdate, doc_diff::Diff> _update;
};
} // namespace write_ops