bool _run(OperationContext* txn, const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            if( cmdObj["replSetReconfig"].type() != Object ) {
                errmsg = "no configuration specified";
                return false;
            }

            ReplicationCoordinator::ReplSetReconfigArgs parsedArgs;
            parsedArgs.newConfigObj =  cmdObj["replSetReconfig"].Obj();
            parsedArgs.force = cmdObj.hasField("force") && cmdObj["force"].trueValue();
            Status status = getGlobalReplicationCoordinator()->processReplSetReconfig(txn,
                                                                                      parsedArgs,
                                                                                      &result);
            return appendCommandStatus(result, status);
        }
Status checkAuthForApplyOpsCommand(OperationContext* txn,
                                   const std::string& dbname,
                                   const BSONObj& cmdObj) {
    AuthorizationSession* authSession = AuthorizationSession::get(txn->getClient());

    ApplyOpsValidity validity = validateApplyOpsCommand(cmdObj);
    if (validity == ApplyOpsValidity::kNeedsSuperuser) {
        std::vector<Privilege> universalPrivileges;
        RoleGraph::generateUniversalPrivileges(&universalPrivileges);
        if (!authSession->isAuthorizedForPrivileges(universalPrivileges)) {
            return Status(ErrorCodes::Unauthorized, "Unauthorized");
        }
        return Status::OK();
    }
    fassert(40314, validity == ApplyOpsValidity::kOk);

    boost::optional<DisableDocumentValidation> maybeDisableValidation;
    if (shouldBypassDocumentValidationForCommand(cmdObj))
        maybeDisableValidation.emplace(txn);


    const bool alwaysUpsert =
        cmdObj.hasField("alwaysUpsert") ? cmdObj["alwaysUpsert"].trueValue() : true;

    checkBSONType(BSONType::Array, cmdObj.firstElement());
    for (const BSONElement& e : cmdObj.firstElement().Array()) {
        checkBSONType(BSONType::Object, e);
        Status status = checkOperationAuthorization(txn, dbname, e.Obj(), alwaysUpsert);
        if (!status.isOK()) {
            return status;
        }
    }

    BSONElement preconditions = cmdObj["preCondition"];
    if (!preconditions.eoo()) {
        for (const BSONElement& precondition : preconditions.Array()) {
            checkBSONType(BSONType::Object, precondition);
            BSONElement nsElem = precondition.Obj()["ns"];
            checkBSONType(BSONType::String, nsElem);
            NamespaceString nss(nsElem.checkAndGetStringData());

            if (!authSession->isAuthorizedForActionsOnResource(
                    ResourcePattern::forExactNamespace(nss), ActionType::find)) {
                return Status(ErrorCodes::Unauthorized, "Unauthorized to check precondition");
            }
        }
    }

    return Status::OK();
}
StatusWith<std::vector<BSONElement>> DatabasesCloner::_parseListDatabasesResponse(
    BSONObj dbResponse) {
    if (!dbResponse.hasField("databases")) {
        return Status(ErrorCodes::BadValue,
                      "The 'listDatabases' response does not contain a 'databases' field.");
    }
    BSONElement response = dbResponse["databases"];
    try {
        return response.Array();
    } catch (const AssertionException&) {
        return Status(ErrorCodes::BadValue,
                      "The 'listDatabases' response is unable to be transformed into an array.");
    }
}
Exemple #4
0
 bool run(
     const string& db,
     BSONObj& cmdObj,
     int options, string& errmsg,
     BSONObjBuilder& result,
     bool fromRepl = false )
 {
     if (cmdObj.hasField("reset")) {
         ReplSetConfig::OPLOG_VERSION = ReplSetConfig::OPLOG_VERSION_CURRENT;
     }
     else {
         ReplSetConfig::OPLOG_VERSION = ReplSetConfig::OPLOG_VERSION_TEST;
     }
     return true;
 }
Exemple #5
0
StatusWith<std::vector<BSONElement>> CollectionCloner::_parseParallelCollectionScanResponse(
    BSONObj resp) {
    if (!resp.hasField("cursors")) {
        return Status(ErrorCodes::CursorNotFound,
                      "The 'parallelCollectionScan' response does not contain a 'cursors' field.");
    }
    BSONElement response = resp["cursors"];
    if (response.type() == BSONType::Array) {
        return response.Array();
    } else {
        return Status(
            ErrorCodes::FailedToParse,
            "The 'parallelCollectionScan' response is unable to be transformed into an array.");
    }
}
        virtual bool run(OperationContext* txn, const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            if( !check(errmsg, result) )
                return false;

            bool force = cmdObj.hasField("force") && cmdObj["force"].trueValue();
            int secs = (int) cmdObj.firstElement().numberInt();
            if( secs == 0 )
                secs = 60;

            Status status = getGlobalReplicationCoordinator()->stepDown(
                    force,
                    ReplicationCoordinator::Milliseconds(0),
                    ReplicationCoordinator::Milliseconds(secs * 1000));
            return appendCommandStatus(result, status);
        }
Exemple #7
0
int CMongodbModel::GetIntFieldValue(BSONObj boRecord, string strFieldName, 
									int iExceptionValue)
{
	int iValue = iExceptionValue;
	if (boRecord.hasField(strFieldName))
	{		
		try 
		{
			iValue = boRecord.getIntField(strFieldName.c_str());
		}
		catch(exception& ex) {}
	}

	return iValue;
}
    Status V1UserDocumentParser::initializeUserCredentialsFromUserDocument(
            User* user, const BSONObj& privDoc) const {
        User::CredentialData credentials;
        if (privDoc.hasField(AuthorizationManager::PASSWORD_FIELD_NAME)) {
            credentials.password = privDoc[AuthorizationManager::PASSWORD_FIELD_NAME].String();
            credentials.isExternal = false;
        }
        else if (privDoc.hasField(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME)) {
            std::string userSource = privDoc[AuthorizationManager::V1_USER_SOURCE_FIELD_NAME].String();
            if (userSource != "$external") {
                return Status(ErrorCodes::UnsupportedFormat,
                              "Cannot extract credentials from user documents without a password "
                              "and with userSource != \"$external\"");
            } else {
                credentials.isExternal = true;
            }
        } else {
            return Status(ErrorCodes::UnsupportedFormat,
                          "Invalid user document: must have one of \"pwd\" and \"userSource\"");
        }

        user->setCredentials(credentials);
        return Status::OK();
    }
Status AuthzManagerExternalStateMock::updateOne(OperationContext* txn,
                                                const NamespaceString& collectionName,
                                                const BSONObj& query,
                                                const BSONObj& updatePattern,
                                                bool upsert,
                                                const BSONObj& writeConcern) {
    namespace mmb = mutablebson;
    UpdateDriver::Options updateOptions;
    UpdateDriver driver(updateOptions);
    Status status = driver.parse(updatePattern);
    if (!status.isOK())
        return status;

    BSONObjCollection::iterator iter;
    status = _findOneIter(collectionName, query, &iter);
    mmb::Document document;
    if (status.isOK()) {
        document.reset(*iter, mmb::Document::kInPlaceDisabled);
        BSONObj logObj;
        status = driver.update(StringData(), &document, &logObj);
        if (!status.isOK())
            return status;
        BSONObj newObj = document.getObject().copy();
        *iter = newObj;
        BSONObj idQuery = driver.makeOplogEntryQuery(newObj, false);

        if (_authzManager) {
            _authzManager->logOp(txn, "u", collectionName.ns().c_str(), logObj, &idQuery);
        }

        return Status::OK();
    } else if (status == ErrorCodes::NoMatchingDocument && upsert) {
        if (query.hasField("_id")) {
            document.root().appendElement(query["_id"]);
        }
        status = driver.populateDocumentWithQueryFields(query, NULL, document);
        if (!status.isOK()) {
            return status;
        }
        status = driver.update(StringData(), &document);
        if (!status.isOK()) {
            return status;
        }
        return insert(txn, collectionName, document.getObject(), writeConcern);
    } else {
        return status;
    }
}
Exemple #10
0
        bool run(
            const string& db,
            BSONObj& cmdObj,
            int options, string& errmsg,
            BSONObjBuilder& result,
            bool fromRepl = false )
        {
            if (cmdObj.hasField("keepOplogAlive")) {
                uint64_t val = cmdObj["keepOplogAlive"].numberLong();
                if (theReplSet) {
                    theReplSet->setKeepOplogAlivePeriod(val);
                }
            }

            return true;
        }
 Status AuthorizationManager::buildPrivilegeSet(const std::string& dbname,
                                                const PrincipalName& principal,
                                                const BSONObj& privilegeDocument,
                                                PrivilegeSet* result) {
     if (!privilegeDocument.hasField(ROLES_FIELD_NAME)) {
         // Old-style (v2.2 and prior) privilege document
         return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname,
                                                                principal,
                                                                privilegeDocument,
                                                                result);
     }
     else {
         return _buildPrivilegeSetFromExtendedPrivilegeDocument(
                 dbname, principal, privilegeDocument, result);
     }
 }
/* ****************************************************************************
*
* setCount -
*/
static void setCount(long long inc, const BSONObj& subOrig, BSONObjBuilder* b)
{
  if (subOrig.hasField(CSUB_COUNT))
  {
    long long count = getIntOrLongFieldAsLongF(subOrig, CSUB_COUNT);
    setCount(count + inc, b);
  }
  else
  {
    // In this case we only add if inc is different from 0
    if (inc > 0)
    {
      setCount(inc, b);
    }
  }
}
Exemple #13
0
    Status LiteParsedQuery::init(const string& ns, int ntoskip, int ntoreturn, int queryOptions,
                                 const BSONObj& queryObj, const BSONObj& proj,
                                 bool fromQueryMessage) {
        _ns = ns;
        _ntoskip = ntoskip;
        _ntoreturn = ntoreturn;
        _options = queryOptions;
        _proj = proj.getOwned();

        if (_ntoskip < 0) {
            return Status(ErrorCodes::BadValue, "bad skip value in query");
        }
        
        if (_ntoreturn < 0) {
            // _ntoreturn greater than zero is simply a hint on how many objects to send back per
            // "cursor batch".  A negative number indicates a hard limit.
            _wantMore = false;
            _ntoreturn = -_ntoreturn;
        }

        if (fromQueryMessage) {
            BSONElement queryField = queryObj["query"];
            if (!queryField.isABSONObj()) { queryField = queryObj["$query"]; }
            if (queryField.isABSONObj()) {
                _filter = queryField.embeddedObject().getOwned();
                Status status = initFullQuery(queryObj);
                if (!status.isOK()) { return status; }
            }
            else {
                // TODO: Does this ever happen?
                _filter = queryObj.getOwned();
            }
        }
        else {
            // This is the debugging code path.
            _filter = queryObj.getOwned();
        }

        _hasReadPref = queryObj.hasField("$readPreference");

        if (!isValidSortOrder(_sort)) {
            return Status(ErrorCodes::BadValue, "bad sort specification");
        }
        _sort = normalizeSortOrder(_sort);

        return Status::OK();
    }
Exemple #14
0
    void createCollectionWithOptions(BSONObj obj) {
        BSONObjIterator i(obj);

        // Rebuild obj as a command object for the "create" command.
        // - {create: <name>} comes first, where <name> is the new name for the collection
        // - elements with type Undefined get skipped over
        BSONObjBuilder bo;
        bo.append("create", _curcoll);
        while (i.more()) {
            BSONElement e = i.next();

            if (strcmp(e.fieldName(), "create") == 0) {
                continue;
            }

            if (e.type() == Undefined) {
                log() << _curns << ": skipping undefined field: " << e.fieldName() << endl;
                continue;
            }

            bo.append(e);
        }
        obj = bo.obj();

        BSONObj fields = BSON("options" << 1);
        scoped_ptr<DBClientCursor> cursor(conn().query(_curdb + ".system.namespaces", Query(BSON("name" << _curns)), 0, 0, &fields));

        bool createColl = true;
        if (cursor->more()) {
            createColl = false;
            BSONObj nsObj = cursor->next();
            if (!nsObj.hasField("options") || !optionsSame(obj, nsObj["options"].Obj())) {
                    log() << "WARNING: collection " << _curns << " exists with different options than are in the metadata.json file and not using --drop. Options in the metadata file will be ignored." << endl;
            }
        }

        if (!createColl) {
            return;
        }

        BSONObj info;
        if (!conn().runCommand(_curdb, obj, info)) {
            uasserted(15936, "Creating collection " + _curns + " failed. Errmsg: " + info["errmsg"].String());
        } else {
            log() << "\tCreated collection " << _curns << " with options: " << obj.jsonString() << endl;
        }
    }
/* ****************************************************************************
*
* setSubject -
*/
static void setSubject(Subscription* s, const BSONObj& r)
{
  // Entities
  std::vector<BSONElement> ents = getField(r, CSUB_ENTITIES).Array();
  for (unsigned int ix = 0; ix < ents.size(); ++ix)
  {
    BSONObj ent           = ents[ix].embeddedObject();
    std::string id        = getStringField(ent, CSUB_ENTITY_ID);
    std::string type      = ent.hasField(CSUB_ENTITY_TYPE)? getStringField(ent, CSUB_ENTITY_TYPE) : "";
    std::string isPattern = getStringField(ent, CSUB_ENTITY_ISPATTERN);

    EntID en;
    if (isFalse(isPattern))
    {
      en.id = id;
    }
    else
    {
      en.idPattern = id;
    }
    en.type = type;

    s->subject.entities.push_back(en);
  }

  // Condition
  std::vector<BSONElement> conds = getField(r, CSUB_CONDITIONS).Array();
  for (unsigned int ix = 0; ix < conds.size(); ++ix)
  {
    BSONObj cond = conds[ix].embeddedObject();
    // The ONCHANGE check is needed, as a subscription could mix different conditions types in DB
    if (std::string(getStringField(cond, CSUB_CONDITIONS_TYPE)) == "ONCHANGE")
    {
      std::vector<BSONElement> condValues = getField(cond, CSUB_CONDITIONS_VALUE).Array();
      for (unsigned int jx = 0; jx < condValues.size(); ++jx)
      {
        std::string attr = condValues[jx].String();
        s->subject.condition.attributes.push_back(attr);
      }
    }
  }

  // Note that current DB model is based on NGSIv1 and doesn't consider expressions. Thus
  // subject.condition.expression cannot be filled. The implemetion will be enhanced once
  // the DB model gets defined
  // TBD
}
/* ****************************************************************************
*
* setDescription -
*/
static void setDescription(const SubscriptionUpdate& subUp, const BSONObj& subOrig, BSONObjBuilder* b)
{
  if (subUp.descriptionProvided)
  {
    setDescription(subUp, b);
  }
  else
  {
    if (subOrig.hasField(CSUB_DESCRIPTION))
    {
      std::string description = getStringFieldF(subOrig, CSUB_DESCRIPTION);

      b->append(CSUB_DESCRIPTION, description);
      LM_T(LmtMongo, ("Subscription description: %s", description.c_str()));
    }
  }
}
    Value DocumentSourceCursor::serialize(bool explain) const {
        // we never parse a documentSourceCursor, so we only serialize for explain
        if (!explain)
            return Value();

        // Get planner-level explain info from the underlying PlanExecutor.
        BSONObjBuilder explainBuilder;
        Status explainStatus(ErrorCodes::InternalError, "");
        {
            const NamespaceString nss(_ns);
            AutoGetCollectionForRead autoColl(pExpCtx->opCtx, nss);

            massert(17392, "No _exec. Were we disposed before explained?", _exec);

            _exec->restoreState(pExpCtx->opCtx);
            explainStatus = Explain::explainStages(pExpCtx->opCtx,
                                                   _exec.get(),
                                                   ExplainCommon::QUERY_PLANNER,
                                                   &explainBuilder);
            _exec->saveState();
        }

        MutableDocument out;
        out["query"] = Value(_query);

        if (!_sort.isEmpty())
            out["sort"] = Value(_sort);

        if (_limit)
            out["limit"] = Value(_limit->getLimit());

        if (!_projection.isEmpty())
            out["fields"] = Value(_projection);

        // Add explain results from the query system into the agg explain output.
        if (explainStatus.isOK()) {
            BSONObj explainObj = explainBuilder.obj();
            invariant(explainObj.hasField("queryPlanner"));
            out["queryPlanner"] = Value(explainObj["queryPlanner"]);
        }
        else {
            out["planError"] = Value(explainStatus.toString());
        }

        return Value(DOC(getSourceName() << out.freezeToValue()));
    }
/* ****************************************************************************
*
* setThrottling -
*/
static void setThrottling(const SubscriptionUpdate& subUp, const BSONObj& subOrig, BSONObjBuilder* b)
{
  if (subUp.throttlingProvided)
  {
    setThrottling(subUp, b);
  }
  else
  {
    if (subOrig.hasField(CSUB_THROTTLING))
    {
      long long throttling = getIntOrLongFieldAsLongF(subOrig, CSUB_THROTTLING);

      b->append(CSUB_THROTTLING, throttling);
      LM_T(LmtMongo, ("Subscription throttling: %lu", throttling));
    }
  }
}
/* ****************************************************************************
*
* setStatus -
*/
static void setStatus(const SubscriptionUpdate& subUp, const BSONObj& subOrig, BSONObjBuilder* b)
{
  if (subUp.statusProvided)
  {
    setStatus(subUp, b);
  }
  else
  {
    if (subOrig.hasField(CSUB_STATUS))
    {
      std::string status = getStringFieldF(subOrig, CSUB_STATUS);

      b->append(CSUB_STATUS, status);
      LM_T(LmtMongo, ("Subscription status: %s", status.c_str()));
    }
  }
}
/* ****************************************************************************
*
* setExpiration -
*/
static void setExpiration(const SubscriptionUpdate& subUp, const BSONObj& subOrig, BSONObjBuilder* b)
{
  if (subUp.expiresProvided)
  {
    setExpiration(subUp, b);
  }
  else
  {
    if (subOrig.hasField(CSUB_EXPIRATION))
    {
      int64_t expires = getIntOrLongFieldAsLongF(subOrig, CSUB_EXPIRATION);

      b->append(CSUB_EXPIRATION, (long long) expires);
      LM_T(LmtMongo, ("Subscription expiration: %lu", expires));
    }
  }
}
Status ShardingEgressMetadataHook::_advanceConfigOptimeFromShard(ShardId shardId,
                                                                 const BSONObj& metadataObj) {
    try {
        auto shard = grid.shardRegistry()->getShardNoReload(shardId);
        if (!shard) {
            return Status::OK();
        }

        // Update our notion of the config server opTime from the configOpTime in the response.
        if (shard->isConfig()) {
            // Config servers return the config opTime as part of their own metadata.
            if (metadataObj.hasField(rpc::kReplSetMetadataFieldName)) {
                auto parseStatus = rpc::ReplSetMetadata::readFromMetadata(metadataObj);
                if (!parseStatus.isOK()) {
                    return parseStatus.getStatus();
                }

                // Use the last committed optime to advance config optime.
                // For successful majority writes, we could use the optime of the last op
                // from us and lastOpCommitted is always greater than or equal to it.
                // On majority write failures, the last visible optime would be incorrect
                // due to rollback as explained in SERVER-24630 and the last committed optime
                // is safe to use.
                const auto& replMetadata = parseStatus.getValue();
                auto opTime = replMetadata.getLastOpCommitted();
                grid.advanceConfigOpTime(opTime);
            }
        } else {
            // Regular shards return the config opTime as part of ConfigServerMetadata.
            auto parseStatus = rpc::ConfigServerMetadata::readFromMetadata(metadataObj);
            if (!parseStatus.isOK()) {
                return parseStatus.getStatus();
            }

            const auto& configMetadata = parseStatus.getValue();
            auto opTime = configMetadata.getOpTime();
            if (opTime.is_initialized()) {
                grid.advanceConfigOpTime(opTime.get());
            }
        }
        return Status::OK();
    } catch (...) {
        return exceptionToStatus();
    }
}
Exemple #22
0
    BSONObj ShardedCursor::concatQuery( const BSONObj& query , const BSONObj& extraFilter ){
        if ( ! query.hasField( "query" ) )
            return _concatFilter( query , extraFilter );
        
        BSONObjBuilder b;
        BSONObjIterator i( query );
        while ( i.more() ){
            BSONElement e = i.next();

            if ( strcmp( e.fieldName() , "query" ) ){
                b.append( e );
                continue;
            }
            
            b.append( "query" , _concatFilter( e.embeddedObjectUserCheck() , extraFilter ) );
        }
        return b.obj();
    }
Exemple #23
0
    void WriteResult::_createWriteError(const BSONObj& error, const std::vector<WriteOperation*>& ops) {
        int batchIndex = _getIntOrDefault(error, "index");
        int code = _getIntOrDefault(error, "code", kUnknownError);

        BSONObjBuilder bob;
        bob.append("index", static_cast<long long>(ops[batchIndex]->getBulkIndex()));
        bob.append("code", code);
        bob.append("errmsg", error.getStringField("errmsg"));

        BSONObjBuilder builder;
        ops[batchIndex]->appendSelfToBSONObj(&builder);
        bob.append("op", builder.obj());

        if (error.hasField("errInfo"))
            bob.append("details", error.getObjectField("errInfo"));

        _writeErrors.push_back(bob.obj());
    }
 Status AuthorizationManager::buildPrivilegeSet(const std::string& dbname,
                                                const PrincipalName& principal,
                                                const BSONObj& privilegeDocument,
                                                PrivilegeSet* result) {
     if (!privilegeDocument.hasField("privileges")) {
         // Old-style (v2.2 and prior) privilege document
         return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname,
                                                                principal,
                                                                privilegeDocument,
                                                                result);
     }
     else {
         return Status(ErrorCodes::UnsupportedFormat,
                       mongoutils::str::stream() << "Invalid privilege document received when "
                               "trying to extract privileges: " << privilegeDocument,
                       0);
     }
 }
    Status AuthzManagerExternalStateMock::updateOne(
            const NamespaceString& collectionName,
            const BSONObj& query,
            const BSONObj& updatePattern,
            bool upsert,
            const BSONObj& writeConcern) {

        namespace mmb = mutablebson;
        UpdateDriver::Options updateOptions;
        updateOptions.upsert = upsert;
        UpdateDriver driver(updateOptions);
        Status status = driver.parse(updatePattern);
        if (!status.isOK())
            return status;

        BSONObjCollection::iterator iter;
        status = _findOneIter(collectionName, query, &iter);
        mmb::Document document;
        if (status.isOK()) {
            document.reset(*iter, mmb::Document::kInPlaceDisabled);
            status = driver.update(StringData(), &document, NULL);
            if (!status.isOK())
                return status;
            *iter = document.getObject().copy();
            return Status::OK();
        }
        else if (status == ErrorCodes::NoMatchingDocument && upsert) {
            if (query.hasField("_id")) {
                document.root().appendElement(query["_id"]);
            }
            status = driver.createFromQuery(query, document);
            if (!status.isOK()) {
                return status;
            }
            status = driver.update(StringData(), &document, NULL);
            if (!status.isOK()) {
                return status;
            }
            return insert(collectionName, document.getObject(), writeConcern);
        }
        else {
            return status;
        }
    }
Exemple #26
0
BSONObj CMongodbModel::ConvertBSONObj(BSONObj boRecord, map<string, string> mapField)
{
	BSONObjBuilder bobCenRecord;
	map<string, string>::iterator mit;
	int iFieldType;
	try{
		for (mit = mapField.begin(); mit != mapField.end(); mit++)
		{
			if (boRecord.hasField(mit->second)){
				iFieldType = boRecord[mit->second].type();
				switch (iFieldType)
				{
				case BSON_STRING_TYPE:
					bobCenRecord.append(mit->first, boRecord.getStringField(mit->second.c_str()));
					break;
				case BSON_INT_TYPE:
					bobCenRecord.append(mit->first, boRecord[mit->second]._numberInt());
					break;
				case BSON_TIMESTAMP_TYPE:
					bobCenRecord.append(mit->first, boRecord[mit->second]._numberLong());
					break;
				case BSON_LONG_LONG_TYPE:
					bobCenRecord.append(mit->first, boRecord[mit->second]._numberLong());
					break;
				default:
					bobCenRecord.append(mit->first, boRecord[mit->second].toString(false));
				}
			}
			else{
				bobCenRecord.append(mit->first, "");
			}
		}
	}
	catch (exception &ex)
	{
		stringstream strErrorMess;
		string strLog;
		strErrorMess << ex.what() << "][" << __FILE__ << "|" << __LINE__;
		strLog = CUtilities::FormatLog(ERROR_MSG, "CMongodbModel", "ConvertBSONObj", "exception:" + strErrorMess.str());
		CUtilities::WriteErrorLog(ERROR_MSG, strLog);
	}
	return bobCenRecord.obj();
}
Exemple #27
0
        /* CmdObj has the form {"hash" : <thingToHash>}
         * or {"hash" : <thingToHash>, "seed" : <number> }
         * Result has the form
         * {"key" : <thingTohash>, "seed" : <int>, "out": NumberLong(<hash>)}
         *
         * Example use in the shell:
         *> db.runCommand({hash: "hashthis", seed: 1})
         *> {"key" : "hashthis",
         *>  "seed" : 1,
         *>  "out" : NumberLong(6271151123721111923),
         *>  "ok" : 1 }
         **/
        bool run(OperationContext* txn, const string& db,
                  BSONObj& cmdObj,
                  int options, string& errmsg,
                  BSONObjBuilder& result){
            result.appendAs(cmdObj.firstElement(),"key");

            int seed = 0;
            if (cmdObj.hasField("seed")){
                if (! cmdObj["seed"].isNumber()) {
                    errmsg += "seed must be a number";
                    return false;
                }
                seed = cmdObj["seed"].numberInt();
            }
            result.append( "seed" , seed );

            result.append( "out" , BSONElementHasher::hash64( cmdObj.firstElement() , seed ) );
            return true;
        }
Status ServerSelectionMetadata::upconvert(const BSONObj& legacyCommand,
                                          const int legacyQueryFlags,
                                          BSONObjBuilder* commandBob,
                                          BSONObjBuilder* metadataBob) {
    // The secondaryOK option is equivalent to the slaveOk bit being set on legacy commands.
    if (legacyQueryFlags & QueryOption_SlaveOk) {
        metadataBob->append(kSecondaryOkFieldName, 1);
    }

    // First we need to check if we have a wrapped command. That is, a command of the form
    // {'$query': { 'commandName': 1, ...}, '$someOption': 5, ....}. Curiously, the field name
    // of the wrapped query can be either '$query', or 'query'.
    auto swUnwrapped = unwrapCommand(legacyCommand);
    if (!swUnwrapped.isOK()) {
        return swUnwrapped.getStatus();
    }

    BSONObj maybeUnwrapped;
    bool wasWrapped;
    std::tie(wasWrapped, maybeUnwrapped) = swUnwrapped.getValue();

    if (wasWrapped) {
        // Check if legacyCommand has an invalid $maxTimeMS option.
        // TODO: Move this check elsewhere when we handle upconverting/downconverting maxTimeMS.
        if (legacyCommand.hasField("$maxTimeMS")) {
            return Status(ErrorCodes::InvalidOptions,
                          "cannot use $maxTimeMS query option with "
                          "commands; use maxTimeMS command option "
                          "instead");
        }

        // If the command was wrapped, we can write out the upconverted command now, as there
        // is nothing else we need to remove from it.
        commandBob->appendElements(maybeUnwrapped);

        return extractWrappedReadPreference(legacyCommand, metadataBob);
    }

    // If the command was not wrapped, we need to check for a readPreference sent by mongos
    // on the $queryOptions field of the command. If it is set, we remove it from the
    // upconverted command, so we need to pass the command builder along.
    return extractUnwrappedReadPreference(maybeUnwrapped, commandBob, metadataBob);
}
Exemple #29
0
 // Compares 2 BSONObj representing collection options. Returns true if the objects
 // represent different options. Ignores the "create" field.
 bool optionsSame(BSONObj obj1, BSONObj obj2) {
     int nfields = 0;
     BSONObjIterator i(obj1);
     while ( i.more() ) {
         BSONElement e = i.next();
         if (!obj2.hasField(e.fieldName())) {
             if (strcmp(e.fieldName(), "create") == 0) {
                 continue;
             } else {
                 return false;
             }
         }
         nfields++;
         if (e != obj2[e.fieldName()]) {
             return false;
         }
     }
     return nfields == obj2.nFields();
 }
        void _delete( Request& r , DbMessage& d, ChunkManagerPtr manager ){

            int flags = d.pullInt();
            bool justOne = flags & 1;
            
            uassert( 10203 ,  "bad delete message" , d.moreJSObjs() );
            BSONObj pattern = d.nextJsObj();

            set<Shard> shards;
            int left = 5;
            
            while ( true ){
                try {
                    manager->getShardsForQuery( shards , pattern );
                    log(2) << "delete : " << pattern << " \t " << shards.size() << " justOne: " << justOne << endl;
                    if ( shards.size() == 1 ){
                        doWrite( dbDelete , r , *shards.begin() );
                        return;
                    }
                    break;
                }
                catch ( StaleConfigException& e ){
                    if ( left <= 0 )
                        throw e;
                    left--;
                    log() << "delete failed b/c of StaleConfigException, retrying " 
                          << " left:" << left << " ns: " << r.getns() << " patt: " << pattern << endl;
                    r.reset( false );
                    shards.clear();
                    manager = r.getChunkManager();
                }
            }
            
            if ( justOne && ! pattern.hasField( "_id" ) )
                throw UserException( 8015 , "can only delete with a non-shard key pattern if can delete as many as we find" );
            
            for ( set<Shard>::iterator i=shards.begin(); i!=shards.end(); i++){
                int * x = (int*)(r.d().afterNS());
                x[0] |= RemoveOption_Broadcast;
                doWrite( dbDelete , r , *i , false );
            }
        }