BSONObj ReadPreferenceSetting::toBSON() const { BSONObjBuilder bob; bob.append(kModeFieldName, readPreferenceName(pref)); if (tags != defaultTagSetForMode(pref)) { bob.append(kTagsFieldName, tags.getTagBSON()); } return bob.obj(); }
StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromBSON(const BSONObj& readPrefObj) { std::string modeStr; auto modeExtractStatus = bsonExtractStringField(readPrefObj, kModeFieldName, &modeStr); if (!modeExtractStatus.isOK()) { return modeExtractStatus; } ReadPreference mode; auto swReadPrefMode = parseReadPreferenceMode(modeStr); if (!swReadPrefMode.isOK()) { return swReadPrefMode.getStatus(); } mode = std::move(swReadPrefMode.getValue()); TagSet tags; BSONElement tagsElem; auto tagExtractStatus = bsonExtractTypedField(readPrefObj, kTagsFieldName, mongo::Array, &tagsElem); if (tagExtractStatus.isOK()) { tags = TagSet{BSONArray(tagsElem.Obj().getOwned())}; // In accordance with the read preference spec, passing the default wildcard tagset // '[{}]' is the same as not passing a TagSet at all. Furthermore, passing an empty // TagSet with a non-primary ReadPreference is equivalent to passing the wildcard // ReadPreference. if (tags == TagSet() || tags == TagSet::primaryOnly()) { tags = defaultTagSetForMode(mode); } // If we are using a user supplied TagSet, check that it is compatible with // the readPreference mode. else if (ReadPreference::PrimaryOnly == mode && (tags != TagSet::primaryOnly())) { return Status(ErrorCodes::BadValue, "Only empty tags are allowed with primary read preference"); } } else if (ErrorCodes::NoSuchKey == tagExtractStatus) { tags = defaultTagSetForMode(mode); } else { return tagExtractStatus; } return ReadPreferenceSetting(mode, tags); }
void ReadPreferenceSetting::toInnerBSON(BSONObjBuilder* bob) const { bob->append(kModeFieldName, readPreferenceName(pref)); if (tags != defaultTagSetForMode(pref)) { bob->append(kTagsFieldName, tags.getTagBSON()); } if (maxStalenessSeconds.count() > 0) { bob->append(kMaxStalenessSecondsFieldName, maxStalenessSeconds.count()); } }
ReadPreferenceSetting::ReadPreferenceSetting(ReadPreference pref) : ReadPreferenceSetting(pref, defaultTagSetForMode(pref)) {}
StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromInnerBSON(const BSONObj& readPrefObj) { std::string modeStr; auto modeExtractStatus = bsonExtractStringField(readPrefObj, kModeFieldName, &modeStr); if (!modeExtractStatus.isOK()) { return modeExtractStatus; } ReadPreference mode; auto swReadPrefMode = parseReadPreferenceMode(modeStr); if (!swReadPrefMode.isOK()) { return swReadPrefMode.getStatus(); } mode = std::move(swReadPrefMode.getValue()); TagSet tags; BSONElement tagsElem; auto tagExtractStatus = bsonExtractTypedField(readPrefObj, kTagsFieldName, mongo::Array, &tagsElem); if (tagExtractStatus.isOK()) { tags = TagSet{BSONArray(tagsElem.Obj().getOwned())}; // In accordance with the read preference spec, passing the default wildcard tagset // '[{}]' is the same as not passing a TagSet at all. Furthermore, passing an empty // TagSet with a non-primary ReadPreference is equivalent to passing the wildcard // ReadPreference. if (tags == TagSet() || tags == TagSet::primaryOnly()) { tags = defaultTagSetForMode(mode); } // If we are using a user supplied TagSet, check that it is compatible with // the readPreference mode. else if (ReadPreference::PrimaryOnly == mode && (tags != TagSet::primaryOnly())) { return Status(ErrorCodes::BadValue, "Only empty tags are allowed with primary read preference"); } } else if (ErrorCodes::NoSuchKey == tagExtractStatus) { tags = defaultTagSetForMode(mode); } else { return tagExtractStatus; } long long maxStalenessSecondsValue; auto maxStalenessSecondsExtractStatus = bsonExtractIntegerFieldWithDefault( readPrefObj, kMaxStalenessSecondsFieldName, 0, &maxStalenessSecondsValue); if (!maxStalenessSecondsExtractStatus.isOK()) { return maxStalenessSecondsExtractStatus; } if (maxStalenessSecondsValue && maxStalenessSecondsValue < 0) { return Status(ErrorCodes::BadValue, str::stream() << kMaxStalenessSecondsFieldName << " must be a non-negative integer"); } if (maxStalenessSecondsValue && maxStalenessSecondsValue >= Seconds::max().count()) { return Status(ErrorCodes::BadValue, str::stream() << kMaxStalenessSecondsFieldName << " value can not exceed " << Seconds::max().count()); } if (maxStalenessSecondsValue && maxStalenessSecondsValue < kMinimalMaxStalenessValue.count()) { return Status(ErrorCodes::MaxStalenessOutOfRange, str::stream() << kMaxStalenessSecondsFieldName << " value can not be less than " << kMinimalMaxStalenessValue.count()); } if ((mode == ReadPreference::PrimaryOnly) && maxStalenessSecondsValue) { return Status(ErrorCodes::BadValue, str::stream() << kMaxStalenessSecondsFieldName << " can not be set for the primary mode"); } return ReadPreferenceSetting(mode, tags, Seconds(maxStalenessSecondsValue)); }
ReadPreferenceSetting::ReadPreferenceSetting(ReadPreference pref, Seconds maxStalenessSeconds) : ReadPreferenceSetting(pref, defaultTagSetForMode(pref), maxStalenessSeconds) {}