summaryrefslogtreecommitdiff
path: root/src/mongo/s/catalog
diff options
context:
space:
mode:
authorJamie Heppenstall <jamie.heppenstall@mongodb.com>2019-06-17 14:42:54 -0400
committerJamie Heppenstall <jamie.heppenstall@mongodb.com>2019-07-12 16:59:06 -0400
commit6e02a4d34bd972e6755bb5f71a5b26f69fe2cfb0 (patch)
tree1a68aa771c357aceb88686004b4f2e730afa17d2 /src/mongo/s/catalog
parent75e47b701d34c9ef7beb0482121ac8b62d2d4991 (diff)
downloadmongo-6e02a4d34bd972e6755bb5f71a5b26f69fe2cfb0.tar.gz
SERVER-41658 Convert ShardCollectionType into an IDL type
Diffstat (limited to 'src/mongo/s/catalog')
-rw-r--r--src/mongo/s/catalog/type_shard_collection.cpp218
-rw-r--r--src/mongo/s/catalog/type_shard_collection.h188
-rw-r--r--src/mongo/s/catalog/type_shard_collection.idl113
-rw-r--r--src/mongo/s/catalog/type_shard_collection_test.cpp155
4 files changed, 224 insertions, 450 deletions
diff --git a/src/mongo/s/catalog/type_shard_collection.cpp b/src/mongo/s/catalog/type_shard_collection.cpp
index 354eec5262f..bc8b3576ee1 100644
--- a/src/mongo/s/catalog/type_shard_collection.cpp
+++ b/src/mongo/s/catalog/type_shard_collection.cpp
@@ -27,214 +27,46 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/s/catalog/type_shard_collection.h"
-#include "mongo/base/status_with.h"
-#include "mongo/bson/bsonobj.h"
-#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/bson/util/bson_extract.h"
-#include "mongo/s/catalog/type_collection.h"
-#include "mongo/util/assert_util.h"
-
namespace mongo {
-const BSONField<std::string> ShardCollectionType::ns("_id");
-const BSONField<UUID> ShardCollectionType::uuid("uuid");
-const BSONField<OID> ShardCollectionType::epoch("epoch");
-const BSONField<BSONObj> ShardCollectionType::keyPattern("key");
-const BSONField<BSONObj> ShardCollectionType::defaultCollation("defaultCollation");
-const BSONField<bool> ShardCollectionType::unique("unique");
-const BSONField<bool> ShardCollectionType::refreshing("refreshing");
-const BSONField<Date_t> ShardCollectionType::lastRefreshedCollectionVersion(
- "lastRefreshedCollectionVersion");
-const BSONField<int> ShardCollectionType::enterCriticalSectionCounter(
- "enterCriticalSectionCounter");
-
-ShardCollectionType::ShardCollectionType(NamespaceString nss,
- boost::optional<UUID> uuid,
- OID epoch,
- const KeyPattern& keyPattern,
- const BSONObj& defaultCollation,
- bool unique)
- : _nss(std::move(nss)),
- _uuid(uuid),
- _epoch(std::move(epoch)),
- _keyPattern(keyPattern.toBSON()),
- _defaultCollation(defaultCollation.getOwned()),
- _unique(unique) {}
+ShardCollectionType::ShardCollectionType(const BSONObj& obj) {
+ ShardCollectionTypeBase::parseProtected(IDLParserErrorContext("ShardCollectionType"), obj);
-StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& source) {
+ uassert(ErrorCodes::ShardKeyNotFound,
+ str::stream() << "Empty shard key. Failed to parse: " << obj.toString(),
+ !getKeyPattern().toBSON().isEmpty());
- NamespaceString nss;
- {
- std::string ns;
- Status status = bsonExtractStringField(source, ShardCollectionType::ns.name(), &ns);
- if (!status.isOK()) {
- return status;
- }
- nss = NamespaceString{ns};
- }
-
- boost::optional<UUID> uuid;
- {
- BSONElement uuidElem;
- Status status = bsonExtractTypedField(
- source, ShardCollectionType::uuid.name(), BSONType::BinData, &uuidElem);
- if (status.isOK()) {
- auto uuidWith = UUID::parse(uuidElem);
- if (!uuidWith.isOK())
- return uuidWith.getStatus();
- uuid = uuidWith.getValue();
- } else if (status == ErrorCodes::NoSuchKey) {
- // The field is not set, which is okay.
- } else {
- return status;
- }
- }
-
- OID epoch;
- {
- BSONElement oidElem;
- Status status = bsonExtractTypedField(
- source, ShardCollectionType::epoch.name(), BSONType::jstOID, &oidElem);
- if (!status.isOK())
- return status;
- epoch = oidElem.OID();
- }
-
- BSONElement collKeyPattern;
- Status status = bsonExtractTypedField(
- source, ShardCollectionType::keyPattern.name(), Object, &collKeyPattern);
- if (!status.isOK()) {
- return status;
- }
- BSONObj obj = collKeyPattern.Obj();
- if (obj.isEmpty()) {
- return Status(ErrorCodes::ShardKeyNotFound,
- str::stream() << "Empty shard key. Failed to parse: " << source.toString());
- }
- KeyPattern pattern(obj.getOwned());
-
- BSONObj collation;
- {
- BSONElement defaultCollation;
- Status status = bsonExtractTypedField(
- source, ShardCollectionType::defaultCollation.name(), Object, &defaultCollation);
- if (status.isOK()) {
- BSONObj obj = defaultCollation.Obj();
- if (obj.isEmpty()) {
- return Status(ErrorCodes::BadValue, "empty defaultCollation");
- }
-
- collation = obj.getOwned();
- } else if (status != ErrorCodes::NoSuchKey) {
- return status;
- }
- }
-
- bool unique;
- {
- Status status =
- bsonExtractBooleanField(source, ShardCollectionType::unique.name(), &unique);
- if (!status.isOK()) {
- return status;
- }
- }
-
- ShardCollectionType shardCollectionType(
- std::move(nss), uuid, std::move(epoch), pattern, collation, unique);
-
- // Below are optional fields.
-
- {
- bool refreshing;
- Status status =
- bsonExtractBooleanField(source, ShardCollectionType::refreshing.name(), &refreshing);
- if (status.isOK()) {
- shardCollectionType.setRefreshing(refreshing);
- } else if (status == ErrorCodes::NoSuchKey) {
- // The field is not set yet, which is okay.
- } else {
- return status;
- }
+ // Last refreshed collection version is stored as a timestamp in the BSON representation of
+ // shard collection type for legacy reasons. We therefore explicitly convert this timestamp, if
+ // it exists, into a chunk version.
+ if (getLastRefreshedCollectionVersion()) {
+ ChunkVersion version = *getLastRefreshedCollectionVersion();
+ setLastRefreshedCollectionVersion(
+ ChunkVersion(version.majorVersion(), version.minorVersion(), getEpoch()));
}
+}
- {
- if (!source[lastRefreshedCollectionVersion.name()].eoo()) {
- auto statusWithLastRefreshedCollectionVersion =
- ChunkVersion::parseLegacyWithField(source, lastRefreshedCollectionVersion());
- if (!statusWithLastRefreshedCollectionVersion.isOK()) {
- return statusWithLastRefreshedCollectionVersion.getStatus();
- }
- auto version = std::move(statusWithLastRefreshedCollectionVersion.getValue());
- shardCollectionType.setLastRefreshedCollectionVersion(
- ChunkVersion(version.majorVersion(), version.minorVersion(), epoch));
- }
+StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& obj) {
+ try {
+ return ShardCollectionType(obj);
+ } catch (const DBException& ex) {
+ return ex.toStatus();
}
-
- return shardCollectionType;
}
BSONObj ShardCollectionType::toBSON() const {
- BSONObjBuilder builder;
+ BSONObj obj = ShardCollectionTypeBase::toBSON();
- builder.append(ns.name(), _nss.ns());
- if (_uuid) {
- _uuid->appendToBuilder(&builder, uuid.name());
+ // Default collation is not included in the BSON representation of shard collection type, and
+ // thus persisted to disk, if it is empty. We therefore explicitly remove default collation from
+ // obj, if it is empty.
+ if (getDefaultCollation().isEmpty()) {
+ obj = obj.removeField(kDefaultCollationFieldName);
}
- builder.append(epoch.name(), _epoch);
- builder.append(keyPattern.name(), _keyPattern.toBSON());
-
- if (!_defaultCollation.isEmpty()) {
- builder.append(defaultCollation.name(), _defaultCollation);
- }
-
- builder.append(unique.name(), _unique);
-
- if (_refreshing) {
- builder.append(refreshing.name(), _refreshing.get());
- }
- if (_lastRefreshedCollectionVersion) {
- builder.appendTimestamp(lastRefreshedCollectionVersion.name(),
- _lastRefreshedCollectionVersion->toLong());
- }
-
- return builder.obj();
-}
-
-std::string ShardCollectionType::toString() const {
- return toBSON().toString();
-}
-
-void ShardCollectionType::setUUID(UUID uuid) {
- _uuid = uuid;
-}
-
-void ShardCollectionType::setNss(NamespaceString nss) {
- invariant(nss.isValid());
- _nss = std::move(nss);
-}
-
-void ShardCollectionType::setEpoch(OID epoch) {
- invariant(epoch.isSet());
- _epoch = std::move(epoch);
-}
-
-void ShardCollectionType::setKeyPattern(const KeyPattern& keyPattern) {
- invariant(!keyPattern.toBSON().isEmpty());
- _keyPattern = keyPattern;
-}
-
-bool ShardCollectionType::getRefreshing() const {
- invariant(_refreshing);
- return _refreshing.get();
-}
-const ChunkVersion& ShardCollectionType::getLastRefreshedCollectionVersion() const {
- invariant(_lastRefreshedCollectionVersion);
- return _lastRefreshedCollectionVersion.get();
+ return obj;
}
} // namespace mongo
diff --git a/src/mongo/s/catalog/type_shard_collection.h b/src/mongo/s/catalog/type_shard_collection.h
index 42d54052f07..95ec62e7775 100644
--- a/src/mongo/s/catalog/type_shard_collection.h
+++ b/src/mongo/s/catalog/type_shard_collection.h
@@ -29,158 +29,58 @@
#pragma once
-#include <boost/optional.hpp>
-#include <string>
-
-#include "mongo/db/jsobj.h"
-#include "mongo/db/keypattern.h"
-#include "mongo/db/namespace_string.h"
-#include "mongo/s/chunk_version.h"
-#include "mongo/util/uuid.h"
+#include "mongo/s/catalog/type_shard_collection_gen.h"
namespace mongo {
-class CollectionType;
-class Status;
-template <typename T>
-class StatusWith;
-
-/**
- * This class represents the layout and contents of documents contained in the shard server's
- * config.collections collection. All manipulation of documents coming from that collection should
- * be done with this class.
- *
- * Expected shard server config.collections collection format:
- * {
- * "_id" : "foo.bar",
- * "uuid" : UUID, // optional in 3.6
- * "epoch" : ObjectId("58b6fd76132358839e409e47"), // will remove when UUID becomes available
- * "key" : {
- * "_id" : 1
- * },
- * "defaultCollation" : {
- * "locale" : "fr_CA"
- * },
- * "unique" : false,
- * "refreshing" : true, // optional
- * "lastRefreshedCollectionVersion" : Timestamp(1, 0), // optional
- * "enterCriticalSectionCounter" : 4 // optional
- * }
- *
- * enterCriticalSectionCounter is currently just an OpObserver signal, thus otherwise ignored here.
- */
-class ShardCollectionType {
+class ShardCollectionType : private ShardCollectionTypeBase {
public:
- static const BSONField<std::string> ns; // "_id"
- static const BSONField<UUID> uuid;
- static const BSONField<OID> epoch;
- static const BSONField<BSONObj> keyPattern;
- static const BSONField<BSONObj> defaultCollation;
- static const BSONField<bool> unique;
- static const BSONField<bool> refreshing;
- static const BSONField<Date_t> lastRefreshedCollectionVersion;
- static const BSONField<int> enterCriticalSectionCounter;
-
- ShardCollectionType(NamespaceString nss,
- boost::optional<UUID> uuid,
- OID epoch,
- const KeyPattern& keyPattern,
- const BSONObj& defaultCollation,
- bool unique);
-
- /**
- * Constructs a new ShardCollectionType object from BSON. Also does validation of the contents.
- */
- static StatusWith<ShardCollectionType> fromBSON(const BSONObj& source);
-
- /**
- * Returns the BSON representation of this shard collection type object.
- */
- BSONObj toBSON() const;
-
- /**
- * Returns a std::string representation of the current internal state.
- */
- std::string toString() const;
-
- const NamespaceString& getNss() const {
- return _nss;
+ // Make field names accessible.
+ using ShardCollectionTypeBase::kDefaultCollationFieldName;
+ using ShardCollectionTypeBase::kEnterCriticalSectionCounterFieldName;
+ using ShardCollectionTypeBase::kEpochFieldName;
+ using ShardCollectionTypeBase::kKeyPatternFieldName;
+ using ShardCollectionTypeBase::kLastRefreshedCollectionVersionFieldName;
+ using ShardCollectionTypeBase::kNssFieldName;
+ using ShardCollectionTypeBase::kRefreshingFieldName;
+ using ShardCollectionTypeBase::kUniqueFieldName;
+ using ShardCollectionTypeBase::kUuidFieldName;
+
+ // Make getters and setters accessible.
+ using ShardCollectionTypeBase::getNss;
+ using ShardCollectionTypeBase::setNss;
+ using ShardCollectionTypeBase::getUuid;
+ using ShardCollectionTypeBase::setUuid;
+ using ShardCollectionTypeBase::getEpoch;
+ using ShardCollectionTypeBase::setEpoch;
+ using ShardCollectionTypeBase::getKeyPattern;
+ using ShardCollectionTypeBase::setKeyPattern;
+ using ShardCollectionTypeBase::getDefaultCollation;
+ using ShardCollectionTypeBase::setDefaultCollation;
+ using ShardCollectionTypeBase::getUnique;
+ using ShardCollectionTypeBase::setUnique;
+ using ShardCollectionTypeBase::getRefreshing;
+ using ShardCollectionTypeBase::setRefreshing;
+ using ShardCollectionTypeBase::getLastRefreshedCollectionVersion;
+ using ShardCollectionTypeBase::setLastRefreshedCollectionVersion;
+ using ShardCollectionTypeBase::getEnterCriticalSectionCounter;
+ using ShardCollectionTypeBase::setEnterCriticalSectionCounter;
+
+ ShardCollectionType() : ShardCollectionTypeBase() {}
+
+ ShardCollectionType(NamespaceString nss, OID epoch, KeyPattern keyPattern, bool unique)
+ : ShardCollectionTypeBase(std::move(nss), std::move(epoch), std::move(keyPattern), unique) {
}
- void setNss(NamespaceString nss);
- const boost::optional<UUID> getUUID() const {
- return _uuid;
- }
- void setUUID(UUID uuid);
+ explicit ShardCollectionType(const BSONObj& obj);
- const OID& getEpoch() const {
- return _epoch;
- }
- void setEpoch(OID epoch);
+ // A wrapper around the IDL generated 'ShardCollectionTypeBase::parse' to ensure backwards
+ // compatibility.
+ static StatusWith<ShardCollectionType> fromBSON(const BSONObj& obj);
- const KeyPattern& getKeyPattern() const {
- return _keyPattern;
- }
- void setKeyPattern(const KeyPattern& keyPattern);
-
- const BSONObj& getDefaultCollation() const {
- return _defaultCollation;
- }
- void setDefaultCollation(const BSONObj& collation) {
- _defaultCollation = collation.getOwned();
- }
-
- bool getUnique() const {
- return _unique;
- }
- void setUnique(bool unique) {
- _unique = unique;
- }
-
- bool hasRefreshing() const {
- return _refreshing.is_initialized();
- }
- bool getRefreshing() const;
- void setRefreshing(bool refreshing) {
- _refreshing = refreshing;
- }
-
- bool hasLastRefreshedCollectionVersion() const {
- return _lastRefreshedCollectionVersion.is_initialized();
- }
- const ChunkVersion& getLastRefreshedCollectionVersion() const;
- void setLastRefreshedCollectionVersion(const ChunkVersion& version) {
- _lastRefreshedCollectionVersion = version;
- }
-
-private:
- // The full namespace (with the database prefix).
- NamespaceString _nss;
-
- // The UUID of the collection, if known.
- boost::optional<UUID> _uuid;
-
- // Uniquely identifies this instance of the collection, in case of drop/create.
- OID _epoch;
-
- // Sharding key. If collection is dropped, this is no longer required.
- KeyPattern _keyPattern;
-
- // Optional collection default collation. If empty, implies simple collation.
- BSONObj _defaultCollation;
-
- // Uniqueness of the sharding key.
- bool _unique;
-
- // Refresh fields set by primaries and used by shard secondaries to safely refresh chunk
- // metadata. '_refreshing' indicates whether the chunks collection is currently being updated,
- // which means read results won't provide a complete view of the chunk metadata.
- // '_lastRefreshedCollectionVersion' indicates the collection version of the last complete chunk
- // metadata refresh, and is used to indicate a refresh occurred if the value is different than
- // when the caller last checked -- because 'refreshing' will be false both before and after a
- // refresh occurs.
- boost::optional<bool> _refreshing{boost::none};
- boost::optional<ChunkVersion> _lastRefreshedCollectionVersion{boost::none};
+ // A wrapper around the IDL generated 'ShardCollectionTypeBase::toBSON' to ensure backwards
+ // compatibility.
+ BSONObj toBSON() const;
};
} // namespace mongo
diff --git a/src/mongo/s/catalog/type_shard_collection.idl b/src/mongo/s/catalog/type_shard_collection.idl
new file mode 100644
index 00000000000..fadbebe7d4d
--- /dev/null
+++ b/src/mongo/s/catalog/type_shard_collection.idl
@@ -0,0 +1,113 @@
+# Copyright (C) 2019-present MongoDB, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the Server Side Public License, version 1,
+# as published by MongoDB, Inc.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# Server Side Public License for more details.
+#
+# You should have received a copy of the Server Side Public License
+# along with this program. If not, see
+# <http://www.mongodb.com/licensing/server-side-public-license>.
+#
+# As a special exception, the copyright holders give permission to link the
+# code of portions of this program with the OpenSSL library under certain
+# conditions as described in each individual source file and distribute
+# linked combinations including the program with the OpenSSL library. You
+# must comply with the Server Side Public License in all respects for
+# all of the code used other than as permitted herein. If you modify file(s)
+# with this exception, you may extend this exception to your version of the
+# file(s), but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version. If you delete this
+# exception statement from all source files in the program, then also delete
+# it in the license file.
+#
+
+# ShardCollectionType type
+#
+# This type represents the layout and contents of documents contained in the shard server's
+# config.collections collection. All manipulation of documents coming from that collection should
+# be done with this class.
+#
+# Expected shard server config.collections collection format:
+# {
+# "_id" : "foo.bar",
+# "uuid" : UUID, // optional in 3.6
+# "epoch" : ObjectId("58b6fd76132358839e409e47"), // will remove when UUID becomes available
+# "key" : {
+# "_id" : 1
+# },
+# "defaultCollation" : {
+# "locale" : "fr_CA"
+# },
+# "unique" : false,
+# "refreshing" : true, // optional
+# "lastRefreshedCollectionVersion" : Timestamp(1, 0), // optional
+# "enterCriticalSectionCounter" : 4 // optional
+# }
+#
+
+global:
+ cpp_namespace: "mongo"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+ - "mongo/db/keypattern.idl"
+ - "mongo/s/chunk_version.idl"
+
+structs:
+ ShardCollectionTypeBase:
+ description: "Represents the layout and contents of documents contained in the shard
+ server's config.collections collection."
+ fields:
+ _id:
+ cpp_name: nss
+ type: namespacestring
+ description: "The full namespace (with the database prefix)."
+ optional: false
+ uuid:
+ type: uuid
+ description: "The UUID of the collection, if known."
+ optional: true
+ epoch:
+ type: objectid
+ description: "Uniquely identifies this instance of the collection, in case of
+ drop/create."
+ optional: false
+ key:
+ cpp_name: keyPattern
+ type: KeyPattern
+ description: "Sharding key. If collection is dropped, this is no longer required."
+ optional: false
+ defaultCollation:
+ type: object_owned
+ default: BSONObj()
+ description: "Optional collection default collation. If empty, implies simple
+ collation."
+ optional: false
+ unique:
+ type: bool
+ description: "Uniqueness of the sharding key."
+ optional: false
+ refreshing:
+ type: bool
+ description: "Set by primaries and used by shard secondaries to safely refresh chunk
+ metadata. Indicates whether the chunks collection is current being
+ updated, which means read results won't provide a complete view of the
+ chunk metadata."
+ optional: true
+ lastRefreshedCollectionVersion:
+ type: ChunkVersionLegacy
+ description: "Set by primaries and used by shard secondaries to safely refresh chunk
+ metadata. Indicates the collection version of the last complete chunk
+ metadata refresh, and is used to indicate if a refresh occurred if the
+ value is different than when the caller last checked -- because
+ 'refreshing' will be false both before and after a refresh occurs."
+ optional: true
+ enterCriticalSectionCounter:
+ type: int
+ description: "Currently just an OpObserver signal, thus otherwise ignored."
+ optional: true
diff --git a/src/mongo/s/catalog/type_shard_collection_test.cpp b/src/mongo/s/catalog/type_shard_collection_test.cpp
index 85e3f5636cb..bde4643c186 100644
--- a/src/mongo/s/catalog/type_shard_collection_test.cpp
+++ b/src/mongo/s/catalog/type_shard_collection_test.cpp
@@ -29,11 +29,10 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/s/shard_metadata_util.h"
#include "mongo/s/catalog/type_shard_collection.h"
-#include "mongo/base/status_with.h"
#include "mongo/bson/oid.h"
-#include "mongo/s/catalog/type_collection.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/time_support.h"
@@ -47,133 +46,63 @@ const BSONObj kKeyPattern = BSON("a" << 1);
const BSONObj kDefaultCollation = BSON("locale"
<< "fr_CA");
-TEST(ShardCollectionType, ToFromBSON) {
- const OID epoch = OID::gen();
- const UUID uuid = UUID::gen();
- const ChunkVersion lastRefreshedCollectionVersion(2, 0, epoch);
-
+TEST(ShardCollectionType, FromBSONEmptyShardKeyFails) {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- uuid.appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::epoch(), epoch);
- builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
- builder.append(ShardCollectionType::defaultCollation(), kDefaultCollation);
- builder.append(ShardCollectionType::unique(), true);
- builder.append(ShardCollectionType::refreshing(), false);
- builder.appendTimestamp(ShardCollectionType::lastRefreshedCollectionVersion(),
- lastRefreshedCollectionVersion.toLong());
- BSONObj obj = builder.obj();
-
- ShardCollectionType shardCollectionType = assertGet(ShardCollectionType::fromBSON(obj));
-
- ASSERT_EQUALS(shardCollectionType.getNss(), kNss);
- ASSERT(shardCollectionType.getUUID());
- ASSERT_EQUALS(*shardCollectionType.getUUID(), uuid);
- ASSERT_EQUALS(shardCollectionType.getEpoch(), epoch);
- ASSERT_BSONOBJ_EQ(shardCollectionType.getKeyPattern().toBSON(), kKeyPattern);
- ASSERT_BSONOBJ_EQ(shardCollectionType.getDefaultCollation(), kDefaultCollation);
- ASSERT_EQUALS(shardCollectionType.getUnique(), true);
- ASSERT_EQUALS(shardCollectionType.getRefreshing(), false);
- ASSERT_EQUALS(shardCollectionType.getLastRefreshedCollectionVersion(),
- lastRefreshedCollectionVersion);
-
- ASSERT_BSONOBJ_EQ(obj, shardCollectionType.toBSON());
+ builder.append(ShardCollectionType::kNssFieldName, kNss.ns());
+ builder.append(ShardCollectionType::kEpochFieldName, OID::gen());
+ builder.append(ShardCollectionType::kKeyPatternFieldName, BSONObj());
+ builder.append(ShardCollectionType::kUniqueFieldName, true);
+
+ StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
+ ASSERT_EQ(status.getStatus().code(), ErrorCodes::ShardKeyNotFound);
}
-TEST(ShardCollectionType, ToFromShardBSONWithoutOptionals) {
- const OID epoch = OID::gen();
+TEST(ShardCollectionType, FromBSONEpochMatchesLastRefreshedCollectionVersionWhenBSONTimestamp) {
+ OID epoch = OID::gen();
BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- builder.append(ShardCollectionType::epoch(), epoch);
- builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
- builder.append(ShardCollectionType::defaultCollation(), kDefaultCollation);
- builder.append(ShardCollectionType::unique(), true);
- BSONObj obj = builder.obj();
-
- ShardCollectionType shardCollectionType = assertGet(ShardCollectionType::fromBSON(obj));
-
- ASSERT_EQUALS(shardCollectionType.getNss(), kNss);
- ASSERT_EQUALS(shardCollectionType.getEpoch(), epoch);
- ASSERT_BSONOBJ_EQ(shardCollectionType.getKeyPattern().toBSON(), kKeyPattern);
- ASSERT_BSONOBJ_EQ(shardCollectionType.getDefaultCollation(), kDefaultCollation);
- ASSERT_EQUALS(shardCollectionType.getUnique(), true);
- ASSERT_FALSE(shardCollectionType.hasRefreshing());
- ASSERT_FALSE(shardCollectionType.hasLastRefreshedCollectionVersion());
-
- ASSERT_BSONOBJ_EQ(obj, shardCollectionType.toBSON());
-}
+ builder.append(ShardCollectionType::kNssFieldName, kNss.ns());
+ builder.append(ShardCollectionType::kEpochFieldName, epoch);
+ builder.append(ShardCollectionType::kKeyPatternFieldName, kKeyPattern);
+ builder.append(ShardCollectionType::kUniqueFieldName, true);
+ builder.append(ShardCollectionType::kLastRefreshedCollectionVersionFieldName, Timestamp());
-TEST(ShardCollectionType, FromEmptyBSON) {
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(BSONObj());
- ASSERT_FALSE(status.isOK());
-}
+ ShardCollectionType shardCollType = assertGet(ShardCollectionType::fromBSON(builder.obj()));
-TEST(ShardCollectionType, FromBSONNoUUIDIsOK) {
- BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- builder.append(ShardCollectionType::epoch(), OID::gen());
- builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
- builder.append(ShardCollectionType::unique(), true);
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
- ASSERT_OK(status.getStatus());
- ASSERT_FALSE(status.getValue().getUUID());
+ ASSERT_EQ(epoch, shardCollType.getLastRefreshedCollectionVersion()->epoch());
}
-TEST(ShardCollectionType, FromBSONNoNSFails) {
- BSONObjBuilder builder;
- UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::epoch(), OID::gen());
- builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
- builder.append(ShardCollectionType::unique(), true);
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
- ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
- ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::ns());
-}
+TEST(ShardCollectionType, FromBSONEpochMatchesLastRefreshedCollectionVersionWhenDate) {
+ OID epoch = OID::gen();
-TEST(ShardCollectionType, FromBSONNoEpochFails) {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
- builder.append(ShardCollectionType::unique(), true);
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
- ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
- ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::epoch());
-}
+ builder.append(ShardCollectionType::kNssFieldName, kNss.ns());
+ builder.append(ShardCollectionType::kEpochFieldName, epoch);
+ builder.append(ShardCollectionType::kKeyPatternFieldName, kKeyPattern);
+ builder.append(ShardCollectionType::kUniqueFieldName, true);
+ builder.append(ShardCollectionType::kLastRefreshedCollectionVersionFieldName, Date_t());
-TEST(ShardCollectionType, FromBSONNoShardKeyFails) {
- BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::epoch(), OID::gen());
- builder.append(ShardCollectionType::unique(), true);
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
- ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
- ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::keyPattern());
-}
+ ShardCollectionType shardCollType = assertGet(ShardCollectionType::fromBSON(builder.obj()));
-TEST(ShardCollectionType, FromBSONNoUniqueFails) {
- BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::epoch(), OID::gen());
- builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
- builder.append(ShardCollectionType::defaultCollation(), kDefaultCollation);
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
- ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
- ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::unique());
+ ASSERT_EQ(epoch, shardCollType.getLastRefreshedCollectionVersion()->epoch());
}
-TEST(ShardCollectionType, FromBSONNoDefaultCollationIsOK) {
- BSONObjBuilder builder;
- builder.append(ShardCollectionType::ns.name(), kNss.ns());
- UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
- builder.append(ShardCollectionType::epoch(), OID::gen());
- builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
- builder.append(ShardCollectionType::unique(), true);
+TEST(ShardCollectionType, ToBSONEmptyDefaultCollationNotIncluded) {
+ ShardCollectionType shardCollType;
+ shardCollType.setNss(kNss);
+ shardCollType.setEpoch(OID::gen());
+ shardCollType.setKeyPattern(kKeyPattern);
+ shardCollType.setUnique(true);
+
+ shardCollType.setDefaultCollation(BSONObj());
+ BSONObj obj = shardCollType.toBSON();
+
+ ASSERT_FALSE(obj.hasField(ShardCollectionType::kDefaultCollationFieldName));
+
+ shardCollType.setDefaultCollation(kDefaultCollation);
+ obj = shardCollType.toBSON();
- assertGet(ShardCollectionType::fromBSON(builder.obj()));
+ ASSERT_TRUE(obj.hasField(ShardCollectionType::kDefaultCollationFieldName));
}
} // namespace