本文整理汇总了C++中WriteConcernOptions::parse方法的典型用法代码示例。如果您正苦于以下问题:C++ WriteConcernOptions::parse方法的具体用法?C++ WriteConcernOptions::parse怎么用?C++ WriteConcernOptions::parse使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WriteConcernOptions
的用法示例。
在下文中一共展示了WriteConcernOptions::parse方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: create
StatusWith<MigrationSecondaryThrottleOptions>
MigrationSecondaryThrottleOptions::createFromBalancerConfig(const BSONObj& obj) {
{
bool isSecondaryThrottle;
Status status =
bsonExtractBooleanField(obj, kSecondaryThrottleMongos, &isSecondaryThrottle);
if (status.isOK()) {
return MigrationSecondaryThrottleOptions::create(isSecondaryThrottle ? kOn : kOff);
} else if (status == ErrorCodes::NoSuchKey) {
return MigrationSecondaryThrottleOptions::create(kDefault);
} else if (status != ErrorCodes::TypeMismatch) {
return status;
}
}
// Try to load it as a BSON document
BSONElement elem;
Status status = bsonExtractTypedField(obj, kSecondaryThrottleMongos, BSONType::Object, &elem);
WriteConcernOptions writeConcern;
Status writeConcernParseStatus = writeConcern.parse(elem.Obj());
if (!writeConcernParseStatus.isOK()) {
return writeConcernParseStatus;
}
return MigrationSecondaryThrottleOptions::createWithWriteConcern(writeConcern);
}
示例2: bsonExtractTypedField
StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand(
const BSONObj& cmdObj, const std::string& dbName, const WriteConcernOptions& defaultWC) {
WriteConcernOptions writeConcern = defaultWC;
writeConcern.usedDefault = true;
if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) {
writeConcern.wNumNodes = 1;
}
BSONElement writeConcernElement;
Status wcStatus = bsonExtractTypedField(cmdObj, "writeConcern", Object, &writeConcernElement);
if (!wcStatus.isOK()) {
if (wcStatus == ErrorCodes::NoSuchKey) {
// Return default write concern if no write concern is given.
return writeConcern;
}
return wcStatus;
}
BSONObj writeConcernObj = writeConcernElement.Obj();
// Empty write concern is interpreted to default.
if (writeConcernObj.isEmpty()) {
return writeConcern;
}
wcStatus = writeConcern.parse(writeConcernObj);
writeConcern.usedDefault = false;
if (!wcStatus.isOK()) {
return wcStatus;
}
return writeConcern;
}
示例3: getWriteConcern
WriteConcernOptions MigrationSecondaryThrottleOptions::getWriteConcern() const {
invariant(_secondaryThrottle != kOff);
invariant(_writeConcernBSON);
WriteConcernOptions writeConcern;
fassertStatusOK(34414, writeConcern.parse(*_writeConcernBSON));
return writeConcern;
}
示例4: MigrationSecondaryThrottleOptions
StatusWith<MigrationSecondaryThrottleOptions> MigrationSecondaryThrottleOptions::createFromCommand(
const BSONObj& obj) {
SecondaryThrottleOption secondaryThrottle;
boost::optional<BSONObj> writeConcernBSON;
// Parse the two variants of the 'secondaryThrottle' option
{
bool isSecondaryThrottle;
Status status =
bsonExtractBooleanField(obj, kSecondaryThrottleMongod, &isSecondaryThrottle);
if (status == ErrorCodes::NoSuchKey) {
status = bsonExtractBooleanField(obj, kSecondaryThrottleMongos, &isSecondaryThrottle);
}
if (status == ErrorCodes::NoSuchKey) {
secondaryThrottle = kDefault;
} else if (status.isOK()) {
secondaryThrottle = (isSecondaryThrottle ? kOn : kOff);
} else {
return status;
}
}
// Extract the requested 'writeConcern' option
{
BSONElement writeConcernElem;
Status status = bsonExtractField(obj, kWriteConcern, &writeConcernElem);
if (status == ErrorCodes::NoSuchKey) {
return MigrationSecondaryThrottleOptions(secondaryThrottle, boost::none);
} else if (!status.isOK()) {
return status;
}
if (secondaryThrottle != kOn) {
return Status(ErrorCodes::UnsupportedFormat,
"Cannot specify write concern when secondaryThrottle is not set");
}
writeConcernBSON = writeConcernElem.Obj().getOwned();
}
invariant(writeConcernBSON.is_initialized());
// Make sure the write concern parses correctly
WriteConcernOptions writeConcern;
Status status = writeConcern.parse(*writeConcernBSON);
if (!status.isOK()) {
return status;
}
return MigrationSecondaryThrottleOptions(secondaryThrottle, std::move(writeConcernBSON));
}
示例5: run
bool run(const string& dbname, BSONObj& _cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
LastError *le = lastError.disableForCommand();
if ( le->nPrev != 1 ) {
LastError::noError.appendSelf( result , false );
le->appendSelfStatus( result );
}
else {
le->appendSelf( result , false );
}
Client& c = cc();
c.appendLastOp( result );
result.appendNumber( "connectionId" , c.getConnectionId() ); // for sharding; also useful in general for debugging
BSONObj cmdObj = _cmdObj;
{
BSONObj::iterator i(_cmdObj);
i.next();
if( !i.more() ) {
/* empty, use default */
BSONObj *def = getLastErrorDefault;
if( def )
cmdObj = *def;
}
}
WriteConcernOptions writeConcern;
Status status = writeConcern.parse( cmdObj );
if ( !status.isOK() ) {
result.append( "badGLE", cmdObj );
errmsg = status.toString();
return false;
}
WriteConcernResult res;
status = waitForWriteConcern( cc(), writeConcern, &res );
res.appendTo( &result );
if ( status.code() == ErrorCodes::WriteConcernLegacyOK ) {
result.append( "wnote", status.toString() );
return true;
}
return appendCommandStatus( result, status );
}
示例6: extractWriteConcern
StatusWith<WriteConcernOptions> extractWriteConcern(const BSONObj& cmdObj,
const std::string& dbName) {
// The default write concern if empty is w : 1
// Specifying w : 0 is/was allowed, but is interpreted identically to w : 1
WriteConcernOptions writeConcern =
repl::getGlobalReplicationCoordinator()->getGetLastErrorDefault();
if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) {
writeConcern.wNumNodes = 1;
}
// Upgrade default write concern if necessary.
addJournalSyncForWMajority(&writeConcern);
BSONElement writeConcernElement;
Status wcStatus = bsonExtractTypedField(cmdObj, "writeConcern", Object, &writeConcernElement);
if (!wcStatus.isOK()) {
if (wcStatus == ErrorCodes::NoSuchKey) {
// Return default write concern if no write concern is given.
return writeConcern;
}
return wcStatus;
}
BSONObj writeConcernObj = writeConcernElement.Obj();
// Empty write concern is interpreted to default.
if (writeConcernObj.isEmpty()) {
return writeConcern;
}
wcStatus = writeConcern.parse(writeConcernObj);
if (!wcStatus.isOK()) {
return wcStatus;
}
wcStatus = validateWriteConcern(writeConcern, dbName);
if (!wcStatus.isOK()) {
return wcStatus;
}
// Upgrade parsed write concern if necessary.
addJournalSyncForWMajority(&writeConcern);
return writeConcern;
}
示例7: bsonExtractTypedField
StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand(
const BSONObj& cmdObj, const std::string& dbName, const WriteConcernOptions& defaultWC) {
WriteConcernOptions writeConcern = defaultWC;
writeConcern.usedDefault = true;
if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) {
writeConcern.wNumNodes = 1;
}
// Return the default write concern if no write concern is provided. We check for the existence
// of the write concern field up front in order to avoid the expense of constructing an error
// status in bsonExtractTypedField() below.
if (!cmdObj.hasField(kWriteConcernField)) {
return writeConcern;
}
BSONElement writeConcernElement;
Status wcStatus =
bsonExtractTypedField(cmdObj, kWriteConcernField, Object, &writeConcernElement);
if (!wcStatus.isOK()) {
return wcStatus;
}
BSONObj writeConcernObj = writeConcernElement.Obj();
// Empty write concern is interpreted to default.
if (writeConcernObj.isEmpty()) {
return writeConcern;
}
wcStatus = writeConcern.parse(writeConcernObj);
writeConcern.usedDefault = false;
if (!wcStatus.isOK()) {
return wcStatus;
}
return writeConcern;
}
示例8: executeBatch
void WriteBatchExecutor::executeBatch( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
// Validate namespace
const NamespaceString nss = NamespaceString( request.getNS() );
if ( !nss.isValid() ) {
toBatchError( Status( ErrorCodes::InvalidNamespace,
nss.ns() + " is not a valid namespace" ),
response );
return;
}
// Make sure we can write to the namespace
Status allowedStatus = userAllowedWriteNS( nss );
if ( !allowedStatus.isOK() ) {
toBatchError( allowedStatus, response );
return;
}
// Validate insert index requests
// TODO: Push insert index requests through createIndex once all upgrade paths support it
string errMsg;
if ( request.isInsertIndexRequest() && !request.isValidIndexRequest( &errMsg ) ) {
toBatchError( Status( ErrorCodes::InvalidOptions, errMsg ), response );
return;
}
// Validate write concern
// TODO: Lift write concern parsing out of this entirely
WriteConcernOptions writeConcern;
BSONObj wcDoc;
if ( request.isWriteConcernSet() ) {
wcDoc = request.getWriteConcern();
}
Status wcStatus = Status::OK();
if ( wcDoc.isEmpty() ) {
// The default write concern if empty is w : 1
// Specifying w : 0 is/was allowed, but is interpreted identically to w : 1
wcStatus = writeConcern.parse(
_defaultWriteConcern.isEmpty() ?
WriteConcernOptions::Acknowledged : _defaultWriteConcern );
if ( writeConcern.wNumNodes == 0 && writeConcern.wMode.empty() ) {
writeConcern.wNumNodes = 1;
}
}
else {
wcStatus = writeConcern.parse( wcDoc );
}
if ( wcStatus.isOK() ) {
wcStatus = validateWriteConcern( writeConcern );
}
if ( !wcStatus.isOK() ) {
toBatchError( wcStatus, response );
return;
}
if ( request.sizeWriteOps() == 0u ) {
toBatchError( Status( ErrorCodes::InvalidLength,
"no write ops were included in the batch" ),
response );
return;
}
// Validate batch size
if ( request.sizeWriteOps() > BatchedCommandRequest::kMaxWriteBatchSize ) {
toBatchError( Status( ErrorCodes::InvalidLength,
stream() << "exceeded maximum write batch size of "
<< BatchedCommandRequest::kMaxWriteBatchSize ),
response );
return;
}
//
// End validation
//
bool silentWC = writeConcern.wMode.empty() && writeConcern.wNumNodes == 0
&& writeConcern.syncMode == WriteConcernOptions::NONE;
Timer commandTimer;
OwnedPointerVector<WriteErrorDetail> writeErrorsOwned;
vector<WriteErrorDetail*>& writeErrors = writeErrorsOwned.mutableVector();
OwnedPointerVector<BatchedUpsertDetail> upsertedOwned;
vector<BatchedUpsertDetail*>& upserted = upsertedOwned.mutableVector();
//
// Apply each batch item, possibly bulking some items together in the write lock.
// Stops on error if batch is ordered.
//
bulkExecute( request, &upserted, &writeErrors );
//.........这里部分代码省略.........
示例9: write
void ClusterWriter::write(OperationContext* txn,
const BatchedCommandRequest& origRequest,
BatchedCommandResponse* response) {
// Add _ids to insert request if req'd
unique_ptr<BatchedCommandRequest> idRequest(BatchedCommandRequest::cloneWithIds(origRequest));
const BatchedCommandRequest* request = NULL != idRequest.get() ? idRequest.get() : &origRequest;
const NamespaceString& nss = request->getNS();
if (!nss.isValid()) {
toBatchError(Status(ErrorCodes::InvalidNamespace, nss.ns() + " is not a valid namespace"),
response);
return;
}
if (!NamespaceString::validCollectionName(nss.coll())) {
toBatchError(
Status(ErrorCodes::BadValue, str::stream() << "invalid collection name " << nss.coll()),
response);
return;
}
if (request->sizeWriteOps() == 0u) {
toBatchError(Status(ErrorCodes::InvalidLength, "no write ops were included in the batch"),
response);
return;
}
if (request->sizeWriteOps() > BatchedCommandRequest::kMaxWriteBatchSize) {
toBatchError(Status(ErrorCodes::InvalidLength,
str::stream() << "exceeded maximum write batch size of "
<< BatchedCommandRequest::kMaxWriteBatchSize),
response);
return;
}
string errMsg;
if (request->isInsertIndexRequest() && !request->isValidIndexRequest(&errMsg)) {
toBatchError(Status(ErrorCodes::InvalidOptions, errMsg), response);
return;
}
// Config writes and shard writes are done differently
const string dbName = nss.db().toString();
unique_ptr<BatchedCommandRequest> requestWithWriteConcern;
if (dbName == "config" || dbName == "admin") {
// w:majority is the only valid write concern for writes to the config servers.
// We also allow w:1 to come in on a user-initiated write, though we convert it here to
// w:majority before sending it to the config servers.
bool rewriteCmdWithWriteConcern = false;
WriteConcernOptions writeConcern;
if (request->isWriteConcernSet()) {
Status status = writeConcern.parse(request->getWriteConcern());
if (!status.isOK()) {
toBatchError(status, response);
return;
}
if (!writeConcern.validForConfigServers()) {
toBatchError(Status(ErrorCodes::InvalidOptions,
"Invalid replication write concern. Writes to config servers "
"must use w:'majority'"),
response);
return;
}
if (writeConcern.wMode == "") {
invariant(writeConcern.wNumNodes == 1);
rewriteCmdWithWriteConcern = true;
}
} else {
rewriteCmdWithWriteConcern = true;
}
if (rewriteCmdWithWriteConcern) {
requestWithWriteConcern.reset(new BatchedCommandRequest(request->getBatchType()));
request->cloneTo(requestWithWriteConcern.get());
writeConcern.wMode = WriteConcernOptions::kMajority;
writeConcern.wNumNodes = 0;
requestWithWriteConcern->setWriteConcern(writeConcern.toBSON());
request = requestWithWriteConcern.get();
}
grid.catalogClient(txn)->writeConfigServerDirect(txn, *request, response);
} else {
TargeterStats targeterStats;
{
ChunkManagerTargeter targeter(request->getTargetingNSS(), &targeterStats);
Status targetInitStatus = targeter.init(txn);
if (!targetInitStatus.isOK()) {
toBatchError(Status(targetInitStatus.code(),
str::stream()
<< "unable to target"
<< (request->isInsertIndexRequest() ? " index" : "")
<< " write op for collection "
<< request->getTargetingNS()
<< causedBy(targetInitStatus)),
response);
return;
}
//.........这里部分代码省略.........
示例10: run
bool run(OperationContext* txn, const string& dbname,
BSONObj& cmdObj,
int,
string& errmsg,
BSONObjBuilder& result,
bool fromRepl ) {
//
// Correct behavior here is very finicky.
//
// 1. The first step is to append the error that occurred on the previous operation.
// This adds an "err" field to the command, which is *not* the command failing.
//
// 2. Next we parse and validate write concern options. If these options are invalid
// the command fails no matter what, even if we actually had an error earlier. The
// reason for checking here is to match legacy behavior on these kind of failures -
// we'll still get an "err" field for the write error.
//
// 3. If we had an error on the previous operation, we then return immediately.
//
// 4. Finally, we actually enforce the write concern. All errors *except* timeout are
// reported with ok : 0.0, to match legacy behavior.
//
// There is a special case when "wOpTime" and "wElectionId" are explicitly provided by
// the client (mongos) - in this case we *only* enforce the write concern if it is
// valid.
//
// We always need to either report "err" (if ok : 1) or "errmsg" (if ok : 0), even if
// err is null.
//
LastError *le = lastError.disableForCommand();
// Always append lastOp and connectionId
Client& c = cc();
c.appendLastOp( result );
// for sharding; also useful in general for debugging
result.appendNumber( "connectionId" , c.getConnectionId() );
OpTime lastOpTime;
BSONField<OpTime> wOpTimeField("wOpTime");
FieldParser::FieldState extracted = FieldParser::extract(cmdObj, wOpTimeField,
&lastOpTime, &errmsg);
if (!extracted) {
result.append("badGLE", cmdObj);
appendCommandStatus(result, false, errmsg);
return false;
}
bool lastOpTimePresent = extracted != FieldParser::FIELD_NONE;
if (!lastOpTimePresent) {
// Use the client opTime if no wOpTime is specified
lastOpTime = cc().getLastOp();
}
OID electionId;
BSONField<OID> wElectionIdField("wElectionId");
extracted = FieldParser::extract(cmdObj, wElectionIdField,
&electionId, &errmsg);
if (!extracted) {
result.append("badGLE", cmdObj);
appendCommandStatus(result, false, errmsg);
return false;
}
bool electionIdPresent = extracted != FieldParser::FIELD_NONE;
bool errorOccurred = false;
// Errors aren't reported when wOpTime is used
if ( !lastOpTimePresent ) {
if ( le->nPrev != 1 ) {
errorOccurred = LastError::noError.appendSelf( result, false );
le->appendSelfStatus( result );
}
else {
errorOccurred = le->appendSelf( result, false );
}
}
BSONObj writeConcernDoc = cmdObj;
// Use the default options if we have no gle options aside from wOpTime/wElectionId
const int nFields = cmdObj.nFields();
bool useDefaultGLEOptions = (nFields == 1) ||
(nFields == 2 && lastOpTimePresent) ||
(nFields == 3 && lastOpTimePresent && electionIdPresent);
if ( useDefaultGLEOptions && getLastErrorDefault ) {
writeConcernDoc = *getLastErrorDefault;
}
//
// Validate write concern no matter what, this matches 2.4 behavior
//
WriteConcernOptions writeConcern;
Status status = writeConcern.parse( writeConcernDoc );
if ( status.isOK() ) {
// Ensure options are valid for this host
status = validateWriteConcern( writeConcern );
//.........这里部分代码省略.........
示例11: executeBatch
void WriteBatchExecutor::executeBatch( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
// TODO: Lift write concern parsing out of this entirely.
WriteConcernOptions writeConcern;
Status status = Status::OK();
BSONObj wcDoc;
if ( request.isWriteConcernSet() ) {
wcDoc = request.getWriteConcern();
}
if ( wcDoc.isEmpty() ) {
status = writeConcern.parse( _defaultWriteConcern );
}
else {
status = writeConcern.parse( wcDoc );
}
if ( status.isOK() ) {
status = validateWriteConcern( writeConcern );
}
if ( !status.isOK() ) {
response->setErrCode( status.code() );
response->setErrMessage( status.reason() );
response->setOk( false );
dassert( response->isValid(NULL) );
return;
}
bool silentWC = writeConcern.wMode.empty() && writeConcern.wNumNodes == 0
&& writeConcern.syncMode == WriteConcernOptions::NONE;
Timer commandTimer;
OwnedPointerVector<WriteErrorDetail> writeErrorsOwned;
vector<WriteErrorDetail*>& writeErrors = writeErrorsOwned.mutableVector();
OwnedPointerVector<BatchedUpsertDetail> upsertedOwned;
vector<BatchedUpsertDetail*>& upserted = upsertedOwned.mutableVector();
//
// Apply each batch item, possibly bulking some items together in the write lock.
// Stops on error if batch is ordered.
//
bulkExecute( request, &upserted, &writeErrors );
//
// Try to enforce the write concern if everything succeeded (unordered or ordered)
// OR if something succeeded and we're unordered.
//
auto_ptr<WCErrorDetail> wcError;
bool needToEnforceWC = writeErrors.empty()
|| ( !request.getOrdered()
&& writeErrors.size() < request.sizeWriteOps() );
if ( needToEnforceWC ) {
_client->curop()->setMessage( "waiting for write concern" );
WriteConcernResult res;
status = waitForWriteConcern( writeConcern, _client->getLastOp(), &res );
if ( !status.isOK() ) {
wcError.reset( toWriteConcernError( status, res ) );
}
}
//
// Refresh metadata if needed
//
bool staleBatch = !writeErrors.empty()
&& writeErrors.back()->getErrCode() == ErrorCodes::StaleShardVersion;
if ( staleBatch ) {
const BatchedRequestMetadata* requestMetadata = request.getMetadata();
dassert( requestMetadata );
// Make sure our shard name is set or is the same as what was set previously
if ( shardingState.setShardName( requestMetadata->getShardName() ) ) {
//
// First, we refresh metadata if we need to based on the requested version.
//
ChunkVersion latestShardVersion;
shardingState.refreshMetadataIfNeeded( request.getTargetingNS(),
requestMetadata->getShardVersion(),
&latestShardVersion );
// Report if we're still changing our metadata
// TODO: Better reporting per-collection
if ( shardingState.inCriticalMigrateSection() ) {
noteInCriticalSection( writeErrors.back() );
}
//.........这里部分代码省略.........
示例12: request
StatusWith<FindAndModifyRequest> FindAndModifyRequest::parseFromBSON(NamespaceString fullNs,
const BSONObj& cmdObj) {
BSONObj query;
BSONObj fields;
BSONObj updateObj;
BSONObj sort;
boost::optional<write_ops::UpdateModification> update;
BSONObj collation;
bool shouldReturnNew = false;
bool isUpsert = false;
bool isRemove = false;
bool bypassDocumentValidation = false;
bool arrayFiltersSet = false;
std::vector<BSONObj> arrayFilters;
bool writeConcernOptionsSet = false;
WriteConcernOptions writeConcernOptions;
for (auto&& field : cmdObj.getFieldNames<std::set<std::string>>()) {
if (field == kQueryField) {
query = cmdObj.getObjectField(kQueryField);
} else if (field == kSortField) {
sort = cmdObj.getObjectField(kSortField);
} else if (field == kRemoveField) {
isRemove = cmdObj[kRemoveField].trueValue();
} else if (field == kUpdateField) {
update = write_ops::UpdateModification::parseFromBSON(cmdObj[kUpdateField]);
} else if (field == kNewField) {
shouldReturnNew = cmdObj[kNewField].trueValue();
} else if (field == kFieldProjectionField) {
fields = cmdObj.getObjectField(kFieldProjectionField);
} else if (field == kUpsertField) {
isUpsert = cmdObj[kUpsertField].trueValue();
} else if (field == kBypassDocumentValidationField) {
bypassDocumentValidation = cmdObj[kBypassDocumentValidationField].trueValue();
} else if (field == kCollationField) {
BSONElement collationElt;
Status collationEltStatus =
bsonExtractTypedField(cmdObj, kCollationField, BSONType::Object, &collationElt);
if (!collationEltStatus.isOK() && (collationEltStatus != ErrorCodes::NoSuchKey)) {
return collationEltStatus;
}
if (collationEltStatus.isOK()) {
collation = collationElt.embeddedObject();
}
} else if (field == kArrayFiltersField) {
BSONElement arrayFiltersElt;
Status arrayFiltersEltStatus = bsonExtractTypedField(
cmdObj, kArrayFiltersField, BSONType::Array, &arrayFiltersElt);
if (!arrayFiltersEltStatus.isOK() && (arrayFiltersEltStatus != ErrorCodes::NoSuchKey)) {
return arrayFiltersEltStatus;
}
if (arrayFiltersEltStatus.isOK()) {
arrayFiltersSet = true;
for (auto arrayFilter : arrayFiltersElt.embeddedObject()) {
if (arrayFilter.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << "Each array filter must be an object, found "
<< arrayFilter.type()};
}
arrayFilters.push_back(arrayFilter.embeddedObject());
}
}
} else if (field == kWriteConcernField) {
BSONElement writeConcernElt;
Status writeConcernEltStatus = bsonExtractTypedField(
cmdObj, kWriteConcernField, BSONType::Object, &writeConcernElt);
if (!writeConcernEltStatus.isOK()) {
return writeConcernEltStatus;
}
auto status = writeConcernOptions.parse(writeConcernElt.embeddedObject());
if (!status.isOK()) {
return status;
} else {
writeConcernOptionsSet = true;
}
} else if (!isGenericArgument(field) &&
!std::count(_knownFields.begin(), _knownFields.end(), field)) {
return {ErrorCodes::Error(51177),
str::stream() << "BSON field '" << field << "' is an unknown field."};
}
}
if (!isRemove && !update) {
return {ErrorCodes::FailedToParse, "Either an update or remove=true must be specified"};
}
if (isRemove) {
if (update) {
return {ErrorCodes::FailedToParse, "Cannot specify both an update and remove=true"};
}
if (isUpsert) {
return {ErrorCodes::FailedToParse, "Cannot specify both upsert=true and remove=true"};
}
if (shouldReturnNew) {
return {ErrorCodes::FailedToParse,
"Cannot specify both new=true and remove=true;"
" 'remove' always returns the deleted document"};
//.........这里部分代码省略.........
示例13: runUserManagementWriteCommand
bool ShardingCatalogClientImpl::runUserManagementWriteCommand(OperationContext* opCtx,
const std::string& commandName,
const std::string& dbname,
const BSONObj& cmdObj,
BSONObjBuilder* result) {
BSONObj cmdToRun = cmdObj;
{
// Make sure that if the command has a write concern that it is w:1 or w:majority, and
// convert w:1 or no write concern to w:majority before sending.
WriteConcernOptions writeConcern;
writeConcern.reset();
BSONElement writeConcernElement = cmdObj[WriteConcernOptions::kWriteConcernField];
bool initialCmdHadWriteConcern = !writeConcernElement.eoo();
if (initialCmdHadWriteConcern) {
Status status = writeConcern.parse(writeConcernElement.Obj());
if (!status.isOK()) {
return CommandHelpers::appendCommandStatusNoThrow(*result, status);
}
if (!(writeConcern.wNumNodes == 1 ||
writeConcern.wMode == WriteConcernOptions::kMajority)) {
return CommandHelpers::appendCommandStatusNoThrow(
*result,
{ErrorCodes::InvalidOptions,
str::stream() << "Invalid replication write concern. User management write "
"commands may only use w:1 or w:'majority', got: "
<< writeConcern.toBSON()});
}
}
writeConcern.wMode = WriteConcernOptions::kMajority;
writeConcern.wNumNodes = 0;
BSONObjBuilder modifiedCmd;
if (!initialCmdHadWriteConcern) {
modifiedCmd.appendElements(cmdObj);
} else {
BSONObjIterator cmdObjIter(cmdObj);
while (cmdObjIter.more()) {
BSONElement e = cmdObjIter.next();
if (WriteConcernOptions::kWriteConcernField == e.fieldName()) {
continue;
}
modifiedCmd.append(e);
}
}
modifiedCmd.append(WriteConcernOptions::kWriteConcernField, writeConcern.toBSON());
cmdToRun = modifiedCmd.obj();
}
auto response =
Grid::get(opCtx)->shardRegistry()->getConfigShard()->runCommandWithFixedRetryAttempts(
opCtx,
ReadPreferenceSetting{ReadPreference::PrimaryOnly},
dbname,
cmdToRun,
Shard::kDefaultConfigCommandTimeout,
Shard::RetryPolicy::kNotIdempotent);
if (!response.isOK()) {
return CommandHelpers::appendCommandStatusNoThrow(*result, response.getStatus());
}
if (!response.getValue().commandStatus.isOK()) {
return CommandHelpers::appendCommandStatusNoThrow(*result,
response.getValue().commandStatus);
}
if (!response.getValue().writeConcernStatus.isOK()) {
return CommandHelpers::appendCommandStatusNoThrow(*result,
response.getValue().writeConcernStatus);
}
CommandHelpers::filterCommandReplyForPassthrough(response.getValue().response, result);
return true;
}
示例14: request
StatusWith<AggregationRequest> AggregationRequest::parseFromBSON(
NamespaceString nss,
const BSONObj& cmdObj,
boost::optional<ExplainOptions::Verbosity> explainVerbosity) {
// Parse required parameters.
auto pipelineElem = cmdObj[kPipelineName];
auto pipeline = AggregationRequest::parsePipelineFromBSON(pipelineElem);
if (!pipeline.isOK()) {
return pipeline.getStatus();
}
AggregationRequest request(std::move(nss), std::move(pipeline.getValue()));
const std::initializer_list<StringData> optionsParsedElseWhere = {kPipelineName, kCommandName};
bool hasCursorElem = false;
bool hasExplainElem = false;
bool hasFromMongosElem = false;
bool hasNeedsMergeElem = false;
// Parse optional parameters.
for (auto&& elem : cmdObj) {
auto fieldName = elem.fieldNameStringData();
if (QueryRequest::kUnwrappedReadPrefField == fieldName) {
// We expect this field to be validated elsewhere.
request.setUnwrappedReadPref(elem.embeddedObject());
} else if (std::find(optionsParsedElseWhere.begin(),
optionsParsedElseWhere.end(),
fieldName) != optionsParsedElseWhere.end()) {
// Ignore options that are parsed elsewhere.
} else if (kCursorName == fieldName) {
long long batchSize;
auto status =
CursorRequest::parseCommandCursorOptions(cmdObj, kDefaultBatchSize, &batchSize);
if (!status.isOK()) {
return status;
}
hasCursorElem = true;
request.setBatchSize(batchSize);
} else if (kCollationName == fieldName) {
if (elem.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << kCollationName << " must be an object, not a "
<< typeName(elem.type())};
}
request.setCollation(elem.embeddedObject().getOwned());
} else if (QueryRequest::cmdOptionMaxTimeMS == fieldName) {
auto maxTimeMs = QueryRequest::parseMaxTimeMS(elem);
if (!maxTimeMs.isOK()) {
return maxTimeMs.getStatus();
}
request.setMaxTimeMS(maxTimeMs.getValue());
} else if (repl::ReadConcernArgs::kReadConcernFieldName == fieldName) {
if (elem.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << repl::ReadConcernArgs::kReadConcernFieldName
<< " must be an object, not a "
<< typeName(elem.type())};
}
request.setReadConcern(elem.embeddedObject().getOwned());
} else if (kHintName == fieldName) {
if (BSONType::Object == elem.type()) {
request.setHint(elem.embeddedObject());
} else if (BSONType::String == elem.type()) {
request.setHint(BSON("$hint" << elem.valueStringData()));
} else {
return Status(ErrorCodes::FailedToParse,
str::stream()
<< kHintName
<< " must be specified as a string representing an index"
<< " name, or an object representing an index's key pattern");
}
} else if (kCommentName == fieldName) {
if (elem.type() != BSONType::String) {
return {ErrorCodes::TypeMismatch,
str::stream() << kCommentName << " must be a string, not a "
<< typeName(elem.type())};
}
request.setComment(elem.str());
} else if (kExplainName == fieldName) {
if (elem.type() != BSONType::Bool) {
return {ErrorCodes::TypeMismatch,
str::stream() << kExplainName << " must be a boolean, not a "
<< typeName(elem.type())};
}
hasExplainElem = true;
if (elem.Bool()) {
request.setExplain(ExplainOptions::Verbosity::kQueryPlanner);
}
} else if (kFromMongosName == fieldName) {
if (elem.type() != BSONType::Bool) {
return {ErrorCodes::TypeMismatch,
str::stream() << kFromMongosName << " must be a boolean, not a "
<< typeName(elem.type())};
}
//.........这里部分代码省略.........