diff options
Diffstat (limited to 'src/mongo/s/catalog/type_shard_collection.cpp')
-rw-r--r-- | src/mongo/s/catalog/type_shard_collection.cpp | 218 |
1 files changed, 25 insertions, 193 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 |