summaryrefslogtreecommitdiff
path: root/src/mongo/bson
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2017-06-15 00:20:33 -0400
committerGeert Bosch <geert@mongodb.com>2017-06-23 15:11:09 -0400
commita69ae445303fc4821c6745866b3902623a385c1c (patch)
tree177cab03d8078defe675fd0dff15349cc32401c0 /src/mongo/bson
parent3bb0f6030b5609002049ea2156e97fe4c6c05d5d (diff)
downloadmongo-a69ae445303fc4821c6745866b3902623a385c1c.tar.gz
SERVER-27992 Use UUIDs for replication
Diffstat (limited to 'src/mongo/bson')
-rw-r--r--src/mongo/bson/bson_obj_test.cpp20
-rw-r--r--src/mongo/bson/bsonobj.cpp20
-rw-r--r--src/mongo/bson/bsonobj.h7
3 files changed, 47 insertions, 0 deletions
diff --git a/src/mongo/bson/bson_obj_test.cpp b/src/mongo/bson/bson_obj_test.cpp
index 890d3c4580f..5a9360605d5 100644
--- a/src/mongo/bson/bson_obj_test.cpp
+++ b/src/mongo/bson/bson_obj_test.cpp
@@ -608,4 +608,24 @@ TEST(BSONObj, ShareOwnershipWith) {
ASSERT_BSONOBJ_EQ(obj, BSON("a" << 1));
}
+TEST(BSONObj, addField) {
+ auto obj = BSON("a" << 1 << "b" << 2);
+
+ // Check that replacing a field maintains the same ordering and doesn't add a field.
+ auto objA2 = BSON("a" << 2);
+ auto elemA2 = objA2.firstElement();
+ auto addFieldA2 = obj.addField(elemA2);
+ ASSERT_EQ(addFieldA2.nFields(), 2);
+ ASSERT_BSONOBJ_EQ(addFieldA2, BSON("a" << 2 << "b" << 2));
+
+ // Check that adding a new field places it at the end.
+ auto objC3 = BSON("c" << 3);
+ auto elemC3 = objC3.firstElement();
+ auto addFieldC3 = obj.addField(elemC3);
+ ASSERT_BSONOBJ_EQ(addFieldC3, BSON("a" << 1 << "b" << 2 << "c" << 3));
+
+ // Check that after all this obj is unchanged.
+ ASSERT_BSONOBJ_EQ(obj, BSON("a" << 1 << "b" << 2));
+}
+
} // unnamed namespace
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp
index 2f7133a2a63..06f446c9c05 100644
--- a/src/mongo/bson/bsonobj.cpp
+++ b/src/mongo/bson/bsonobj.cpp
@@ -503,6 +503,26 @@ bool BSONObj::getObjectID(BSONElement& e) const {
return false;
}
+BSONObj BSONObj::addField(const BSONElement& field) const {
+ if (!field.ok())
+ return copy();
+ BSONObjBuilder b;
+ StringData name = field.fieldNameStringData();
+ bool added = false;
+ for (auto e : *this) {
+ if (e.fieldNameStringData() == name) {
+ if (!added)
+ b.append(field);
+ added = true;
+ } else {
+ b.append(e);
+ }
+ }
+ if (!added)
+ b.append(field);
+ return b.obj();
+}
+
BSONObj BSONObj::removeField(StringData name) const {
BSONObjBuilder b;
BSONObjIterator i(*this);
diff --git a/src/mongo/bson/bsonobj.h b/src/mongo/bson/bsonobj.h
index 8d62bc8fd3d..15e2326c0db 100644
--- a/src/mongo/bson/bsonobj.h
+++ b/src/mongo/bson/bsonobj.h
@@ -245,6 +245,13 @@ public:
/** note: addFields always adds _id even if not specified */
int addFields(BSONObj& from, std::set<std::string>& fields); /* returns n added */
+ /**
+ * Add specific field to the end of the object if it did not exist, otherwise replace it
+ * preserving original field order. Returns newly built object. Returns copy of this for empty
+ * field.
+ */
+ BSONObj addField(const BSONElement& field) const;
+
/** remove specified field and return a new object with the remaining fields.
slowish as builds a full new object
*/