Status V2UserDocumentParser::parseRoleName(const BSONObj& roleObject, RoleName* result) {
    BSONElement roleNameElement;
    BSONElement roleSourceElement;
    Status status = _extractRoleDocumentElements(roleObject, &roleNameElement, &roleSourceElement);
    if (!status.isOK())
        return status;
    *result = RoleName(roleNameElement.str(), roleSourceElement.str());
    return status;
}
intrusive_ptr<DocumentSource> DocumentSourceOut::createFromBson(
    BSONElement elem, const intrusive_ptr<ExpressionContext>& pExpCtx) {
    uassert(16990,
            str::stream() << "$out only supports a string argument, not " << typeName(elem.type()),
            elem.type() == String);

    NamespaceString outputNs(pExpCtx->ns.db().toString() + '.' + elem.str());
    uassert(17385, "Can't $out to special collection: " + elem.str(), !outputNs.isSpecial());
    return new DocumentSourceOut(outputNs, pExpCtx);
}
Beispiel #3
0
intrusive_ptr<DocumentSource> DocumentSourceOut::createFromBson(
    BSONElement elem, const intrusive_ptr<ExpressionContext>& pExpCtx) {
    uassert(16990,
            str::stream() << "$out only supports a string argument, not " << typeName(elem.type()),
            elem.type() == String);

    uassert(ErrorCodes::InvalidOptions,
            "$out can only be used with the 'local' read concern level",
            !pExpCtx->opCtx->recoveryUnit()->isReadingFromMajorityCommittedSnapshot());

    NamespaceString outputNs(pExpCtx->ns.db().toString() + '.' + elem.str());
    uassert(17385, "Can't $out to special collection: " + elem.str(), !outputNs.isSpecial());
    return new DocumentSourceOut(outputNs, pExpCtx);
}
Beispiel #4
0
Status bsonExtractStringField(const BSONObj& object, StringData fieldName, std::string* out) {
    BSONElement element;
    Status status = bsonExtractTypedField(object, fieldName, String, &element);
    if (status.isOK())
        *out = element.str();
    return status;
}
Beispiel #5
0
    HashedIndexType::HashedIndexType( const IndexPlugin* plugin , const IndexSpec* spec ) :
            IndexType( plugin , spec ) , _keyPattern( spec->keyPattern ) {

        //change these if single-field limitation lifted later
        uassert( 16241 , "Currently only single field hashed index supported." ,
                _keyPattern.toBSON().nFields() == 1 );
        uassert( 16242 , "Currently hashed indexes cannot guarantee uniqueness. Use a regular index." ,
                ! (spec->info).getField("unique").booleanSafe() );

        //Default _seed to 0 if "seed" is not included in the index spec
        //or if the value of "seed" is not a number
        _seed = (spec->info).getField("seed").numberInt();

        //Default _isSparse to false if "sparse" is not included in the index spec
        //or if the value of "sparse" is not a boolean
        _isSparse = (spec->info).getField("sparse").booleanSafe();

        //In case we have hashed indexes based on other hash functions in
        //the future, we store a hashVersion number. If hashVersion changes,
        // "makeSingleKey" will need to change accordingly.
        //Defaults to 0 if "hashVersion" is not included in the index spec
        //or if the value of "hashversion" is not a number
        _hashVersion = (spec->info).getField("hashVersion").numberInt();

        //Get the hashfield name
        BSONElement firstElt = spec->keyPattern.firstElement();
        massert( 16243 , "error: no hashed index field" ,
                firstElt.str().compare( HASHED_INDEX_TYPE_IDENTIFIER ) == 0 );
        _hashedField = firstElt.fieldName();
    }
    Status saslExtractPayload(const BSONObj& cmdObj, std::string* payload, BSONType* type) {
        BSONElement payloadElement;
        Status status = bsonExtractField(cmdObj, saslCommandPayloadFieldName, &payloadElement);
        if (!status.isOK())
            return status;

        *type = payloadElement.type();
        if (payloadElement.type() == BinData) {
            const char* payloadData;
            int payloadLen;
            payloadData = payloadElement.binData(payloadLen);
            if (payloadLen < 0)
                return Status(ErrorCodes::InvalidLength, "Negative payload length");
            *payload = std::string(payloadData, payloadData + payloadLen);
        }
        else if (payloadElement.type() == String) {
            try {
                *payload = base64::decode(payloadElement.str());
            } catch (UserException& e) {
                return Status(ErrorCodes::FailedToParse, e.what());
            }
        }
        else {
            return Status(ErrorCodes::TypeMismatch,
                          (str::stream() << "Wrong type for field; expected BinData or String for "
                           << payloadElement));
        }

        return Status::OK();
    }
Beispiel #7
0
intrusive_ptr<DocumentSource> DocumentSourceOut::createFromBson(
    BSONElement elem, const intrusive_ptr<ExpressionContext>& expCtx) {

    auto mode = WriteModeEnum::kModeReplaceCollection;
    std::set<FieldPath> uniqueKey;
    NamespaceString outputNs;
    boost::optional<ChunkVersion> targetCollectionVersion;
    if (elem.type() == BSONType::String) {
        outputNs = NamespaceString(expCtx->ns.db().toString() + '.' + elem.str());
        uniqueKey.emplace("_id");
    } else if (elem.type() == BSONType::Object) {
        auto spec =
            DocumentSourceOutSpec::parse(IDLParserErrorContext("$out"), elem.embeddedObject());
        mode = spec.getMode();

        // Retrieve the target database from the user command, otherwise use the namespace from the
        // expression context.
        auto dbName = spec.getTargetDb() ? *spec.getTargetDb() : expCtx->ns.db();
        outputNs = NamespaceString(dbName, spec.getTargetCollection());

        std::tie(uniqueKey, targetCollectionVersion) = expCtx->inMongos
            ? resolveUniqueKeyOnMongoS(expCtx, spec, outputNs)
            : resolveUniqueKeyOnMongoD(expCtx, spec, outputNs);
    } else {
        uasserted(16990,
                  str::stream() << "$out only supports a string or object argument, not "
                                << typeName(elem.type()));
    }

    return create(std::move(outputNs), expCtx, mode, std::move(uniqueKey), targetCollectionVersion);
}
    /**
     * Given a database name and a BSONElement representing an array of roles, populates
     * "outPrivileges" with the privileges associated with the given roles on the named database.
     *
     * Returns Status::OK() on success.
     */
    static Status _getPrivilegesFromRoles(const std::string& dbname,
                                          const BSONElement& rolesElement,
                                          std::vector<Privilege>* outPrivileges) {

        static const char privilegesTypeMismatchMessage[] =
            "Roles must be enumerated in an array of strings.";

        if (dbname == PrivilegeSet::WILDCARD_RESOURCE) {
            return Status(ErrorCodes::BadValue,
                          PrivilegeSet::WILDCARD_RESOURCE + " is an invalid database name.");
        }

        if (rolesElement.type() != Array)
            return Status(ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);

        for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) {
            BSONElement roleElement = *iter;
            if (roleElement.type() != String)
                return Status(ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);
            Status status = _addPrivilegesForSystemRole(dbname, roleElement.str(), outPrivileges);
            if (!status.isOK())
                return status;
        }
        return Status::OK();
    }
 MONGO_FAIL_POINT_BLOCK(setYieldAllLocksWait, customWait) {
     const BSONObj& data = customWait.getData();
     BSONElement customWaitNS = data["namespace"];
     if (!customWaitNS || planExecNS.ns() == customWaitNS.str()) {
         sleepFor(Milliseconds(data["waitForMillis"].numberInt()));
     }
 }
Beispiel #10
0
BSONObj SyncTail::getMissingDoc(OperationContext* txn, Database* db, const BSONObj& o) {
    OplogReader missingObjReader;  // why are we using OplogReader to run a non-oplog query?
    const char* ns = o.getStringField("ns");

    // capped collections
    Collection* collection = db->getCollection(ns);
    if (collection && collection->isCapped()) {
        log() << "missing doc, but this is okay for a capped collection (" << ns << ")";
        return BSONObj();
    }

    const int retryMax = 3;
    for (int retryCount = 1; retryCount <= retryMax; ++retryCount) {
        if (retryCount != 1) {
            // if we are retrying, sleep a bit to let the network possibly recover
            sleepsecs(retryCount * retryCount);
        }
        try {
            bool ok = missingObjReader.connect(HostAndPort(_hostname));
            if (!ok) {
                warning() << "network problem detected while connecting to the "
                          << "sync source, attempt " << retryCount << " of " << retryMax << endl;
                continue;  // try again
            }
        } catch (const SocketException&) {
            warning() << "network problem detected while connecting to the "
                      << "sync source, attempt " << retryCount << " of " << retryMax << endl;
            continue;  // try again
        }

        // get _id from oplog entry to create query to fetch document.
        const BSONElement opElem = o.getField("op");
        const bool isUpdate = !opElem.eoo() && opElem.str() == "u";
        const BSONElement idElem = o.getObjectField(isUpdate ? "o2" : "o")["_id"];

        if (idElem.eoo()) {
            severe() << "cannot fetch missing document without _id field: " << o.toString();
            fassertFailedNoTrace(28742);
        }

        BSONObj query = BSONObjBuilder().append(idElem).obj();
        BSONObj missingObj;
        try {
            missingObj = missingObjReader.findOne(ns, query);
        } catch (const SocketException&) {
            warning() << "network problem detected while fetching a missing document from the "
                      << "sync source, attempt " << retryCount << " of " << retryMax << endl;
            continue;  // try again
        } catch (DBException& e) {
            error() << "assertion fetching missing object: " << e.what() << endl;
            throw;
        }

        // success!
        return missingObj;
    }
    // retry count exceeded
    msgasserted(15916,
                str::stream() << "Can no longer connect to initial sync source: " << _hostname);
}
Beispiel #11
0
 string DBClientWithCommands::getLastError() { 
     BSONObj info = getLastErrorDetailed();
     BSONElement e = info["err"];
     if( e.eoo() ) return "";
     if( e.type() == Object ) return e.toString();
     return e.str();
 }
Beispiel #12
0
void ExpressionParams::parseHashParams(const BSONObj& infoObj,
                                       HashSeed* seedOut,
                                       int* versionOut,
                                       std::string* fieldOut) {
    // Default _seed to DEFAULT_HASH_SEED if "seed" is not included in the index spec
    // or if the value of "seed" is not a number

    // *** WARNING ***
    // Choosing non-default seeds will invalidate hashed sharding
    // Changing the seed default will break existing indexes and sharded collections
    if (infoObj["seed"].eoo()) {
        *seedOut = BSONElementHasher::DEFAULT_HASH_SEED;
    } else {
        *seedOut = infoObj["seed"].numberInt();
    }

    // In case we have hashed indexes based on other hash functions in the future, we store
    // a hashVersion number. If hashVersion changes, "makeSingleHashKey" will need to change
    // accordingly.  Defaults to 0 if "hashVersion" is not included in the index spec or if
    // the value of "hashversion" is not a number
    *versionOut = infoObj["hashVersion"].numberInt();

    // Get the hashfield name
    BSONElement firstElt = infoObj.getObjectField("key").firstElement();
    massert(16765, "error: no hashed index field", firstElt.str().compare(IndexNames::HASHED) == 0);
    *fieldOut = firstElt.fieldName();
}
Beispiel #13
0
 string DBClientWithCommands::getLastError() { 
     BSONObj info;
     runCommand("admin", getlasterrorcmdobj, info);
     BSONElement e = info["err"];
     if( e.eoo() ) return "";
     if( e.type() == Object ) return e.toString();
     return e.str();
 }
Beispiel #14
0
 MONGO_FAIL_POINT_BLOCK(planExecutorAlwaysDead, customKill) {
     const BSONObj& data = customKill.getData();
     BSONElement customKillNS = data["namespace"];
     if (!customKillNS || _ns == customKillNS.str()) {
         deregisterExec();
         kill("hit planExecutorAlwaysDead fail point");
     }
 }
Beispiel #15
0
TEST(ExtractBSON, ExtractField) {
    BSONObj obj = BSON("a" << 1 << "b" << "hello");
    BSONElement element;
    ASSERT_OK(bsonExtractField(obj, "a", &element));
    ASSERT_EQUALS(1, element.Int());
    ASSERT_OK(bsonExtractField(obj, "b", &element));
    ASSERT_EQUALS(std::string("hello"), element.str());
    ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractField(obj, "c", &element));
}
Beispiel #16
0
 Status V2UserDocumentParser::parseRoleData(const BSONObj& roleObject, User::RoleData* result) {
     BSONElement roleNameElement;
     BSONElement roleSourceElement;
     BSONElement canDelegateElement;
     BSONElement hasRoleElement;
     Status status =  _extractRoleDocumentElements(
             roleObject,
             &roleNameElement,
             &roleSourceElement,
             &canDelegateElement,
             &hasRoleElement);
     if (!status.isOK())
         return status;
     result->name = RoleName(roleNameElement.str(), roleSourceElement.str());
     result->canDelegate = canDelegateElement.eoo() ? false : canDelegateElement.trueValue();
     result->hasRole = hasRoleElement.eoo() ? true : hasRoleElement.trueValue();
     return status;
 }
intrusive_ptr<DocumentSource> DocumentSourceUnwind::createFromBson(
    BSONElement elem, const intrusive_ptr<ExpressionContext>& pExpCtx) {
    // $unwind accepts either the legacy "{$unwind: '$path'}" syntax, or a nested document with
    // extra options.
    string prefixedPathString;
    bool preserveNullAndEmptyArrays = false;
    boost::optional<string> indexPath;
    if (elem.type() == Object) {
        for (auto&& subElem : elem.Obj()) {
            if (subElem.fieldNameStringData() == "path") {
                uassert(28808,
                        str::stream() << "expected a string as the path for $unwind stage, got "
                                      << typeName(subElem.type()),
                        subElem.type() == String);
                prefixedPathString = subElem.str();
            } else if (subElem.fieldNameStringData() == "preserveNullAndEmptyArrays") {
                uassert(28809,
                        str::stream() << "expected a boolean for the preserveNullAndEmptyArrays "
                                         "option to $unwind stage, got "
                                      << typeName(subElem.type()),
                        subElem.type() == Bool);
                preserveNullAndEmptyArrays = subElem.Bool();
            } else if (subElem.fieldNameStringData() == "includeArrayIndex") {
                uassert(28810,
                        str::stream() << "expected a non-empty string for the includeArrayIndex "
                                         " option to $unwind stage, got "
                                      << typeName(subElem.type()),
                        subElem.type() == String && !subElem.String().empty());
                indexPath = subElem.String();
                uassert(28822,
                        str::stream() << "includeArrayIndex option to $unwind stage should not be "
                                         "prefixed with a '$': " << (*indexPath),
                        (*indexPath)[0] != '$');
            } else {
                uasserted(28811,
                          str::stream() << "unrecognized option to $unwind stage: "
                                        << subElem.fieldNameStringData());
            }
        }
    } else if (elem.type() == String) {
        prefixedPathString = elem.str();
    } else {
        uasserted(
            15981,
            str::stream()
                << "expected either a string or an object as specification for $unwind stage, got "
                << typeName(elem.type()));
    }
    uassert(28812, "no path specified to $unwind stage", !prefixedPathString.empty());

    uassert(28818,
            str::stream() << "path option to $unwind stage should be prefixed with a '$': "
                          << prefixedPathString,
            prefixedPathString[0] == '$');
    string pathString(Expression::removeFieldPrefix(prefixedPathString));
    return DocumentSourceUnwind::create(pExpCtx, pathString, preserveNullAndEmptyArrays, indexPath);
}
 virtual bool run(const string &db, BSONObj &cmdObj, int options, string &errmsg, BSONObjBuilder &result, bool fromRepl) {
     BSONElement e = cmdObj.firstElement();
     string dest = e.str();
     if (dest.empty()) {
         errmsg = "invalid destination directory: '" + dest + "'";
         return false;
     }
     Manager manager(cc());
     return manager.start(dest, errmsg, result);
 }
Beispiel #19
0
TEST(ExtractBSON, ExtractTypedField) {
    BSONObj obj = BSON("a" << 1 << "b" << "hello");
    BSONElement element;
    ASSERT_OK(bsonExtractTypedField(obj, "a", NumberInt, &element));
    ASSERT_EQUALS(1, element.Int());
    ASSERT_OK(bsonExtractTypedField(obj, "b", String, &element));
    ASSERT_EQUALS(std::string("hello"), element.str());
    ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractTypedField(obj, "c", String, &element));
    ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "a", String, &element));
    ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "b", NumberDouble, &element));
}
StatusWith<UpdateZoneKeyRangeRequest> UpdateZoneKeyRangeRequest::_parseFromCommand(
    const BSONObj& cmdObj, bool forMongos) {
    string rawNS;
    auto parseNamespaceStatus = bsonExtractStringField(
        cmdObj, (forMongos ? kMongosUpdateZoneKeyRange : kConfigsvrUpdateZoneKeyRange), &rawNS);

    if (!parseNamespaceStatus.isOK()) {
        return parseNamespaceStatus;
    }

    NamespaceString ns(rawNS);

    if (!ns.isValid()) {
        return {ErrorCodes::InvalidNamespace,
                str::stream() << rawNS << " is not a valid namespace"};
    }

    auto parseRangeStatus = ChunkRange::fromBSON(cmdObj);
    if (!parseRangeStatus.isOK()) {
        return parseRangeStatus.getStatus();
    }

    BSONElement zoneElem;

    auto parseZoneNameStatus = bsonExtractField(cmdObj, kZoneName, &zoneElem);

    if (!parseZoneNameStatus.isOK()) {
        return parseZoneNameStatus;
    }

    bool isRemove = false;
    string zoneName;
    if (zoneElem.type() == String) {
        zoneName = zoneElem.str();
    } else if (zoneElem.isNull()) {
        isRemove = true;
    } else {
        return {ErrorCodes::TypeMismatch,
                str::stream() << "\"" << kZoneName << "\" had the wrong type. Expected "
                              << typeName(String)
                              << " or "
                              << typeName(jstNULL)
                              << ", found "
                              << typeName(zoneElem.type())};
    }

    if (isRemove) {
        return UpdateZoneKeyRangeRequest(std::move(ns), std::move(parseRangeStatus.getValue()));
    }

    return UpdateZoneKeyRangeRequest(
        std::move(ns), std::move(parseRangeStatus.getValue()), std::move(zoneName));
}
Beispiel #21
0
    /**
     * Suppress the "err" and "code" field if they are coming from a previous write error and
     * are not related to write concern.  Also removes any write stats information (e.g. "n")
     *
     * Also, In some cases, 2.4 GLE w/ wOpTime can give us duplicate "err" and "code" fields b/c of
     * reporting a previous error.  The later field is what we want - dedup and use later field.
     *
     * Returns the stripped GLE response.
     */
    BSONObj stripNonWCInfo( const BSONObj& gleResponse ) {

        BSONObjIterator it( gleResponse );
        BSONObjBuilder builder;

        BSONElement codeField; // eoo
        BSONElement errField; // eoo

        while ( it.more() ) {
            BSONElement el = it.next();
            StringData fieldName( el.fieldName() );
            if ( fieldName.compare( "err" ) == 0 ) {
                errField = el;
            }
            else if ( fieldName.compare( "code" ) == 0 ) {
                codeField = el;
            }
            else if ( fieldName.compare( "n" ) == 0 || fieldName.compare( "nModified" ) == 0
                      || fieldName.compare( "upserted" ) == 0
                      || fieldName.compare( "updatedExisting" ) == 0 ) {
                // Suppress field
            }
            else {
                builder.append( el );
            }
        }

        if ( !codeField.eoo() ) {
            if ( !gleResponse["ok"].trueValue() ) {
                // The last code will be from the write concern
                builder.append( codeField );
            }
            else {
                // The code is from a non-wc error on this connection - suppress it
            }
        }

        if ( !errField.eoo() ) {
            string err = errField.str();
            if ( err == "norepl" || err == "noreplset" || err == "timeout" ) {
                // Append err if it's from a write concern issue
                builder.append( errField );
            }
            else {
                // Suppress non-write concern err as null, but we need to report null err if ok
                if ( gleResponse["ok"].trueValue() )
                    builder.appendNull( errField.fieldName() );
            }
        }

        return builder.obj();
    }
Beispiel #22
0
Status bsonExtractStringFieldWithDefault(const BSONObj& object,
                                         StringData fieldName,
                                         StringData defaultValue,
                                         std::string* out) {
    BSONElement element;
    Status status = bsonExtractTypedFieldImpl(object, fieldName, String, &element, true);
    if (status == ErrorCodes::NoSuchKey) {
        *out = defaultValue.toString();
        return Status::OK();
    }
    if (status.isOK())
        *out = element.str();
    return status;
}
Beispiel #23
0
StatusWith<CountRequest> CountRequest::parseFromBSON(const std::string& dbname,
                                                     const BSONObj& cmdObj) {
    BSONElement firstElt = cmdObj.firstElement();
    const std::string coll = (firstElt.type() == BSONType::String) ? firstElt.str() : "";

    const std::string ns = str::stream() << dbname << "." << coll;
    if (!nsIsFull(ns)) {
        return Status(ErrorCodes::BadValue, "invalid collection name");
    }

    // We don't validate that "query" is a nested object due to SERVER-15456.
    CountRequest request(ns, cmdObj.getObjectField(kQueryField));

    // Limit
    if (cmdObj[kLimitField].isNumber()) {
        long long limit = cmdObj[kLimitField].numberLong();

        // For counts, limit and -limit mean the same thing.
        if (limit < 0) {
            limit = -limit;
        }

        request.setLimit(limit);
    } else if (cmdObj[kLimitField].ok()) {
        return Status(ErrorCodes::BadValue, "limit value is not a valid number");
    }

    // Skip
    if (cmdObj[kSkipField].isNumber()) {
        long long skip = cmdObj[kSkipField].numberLong();
        if (skip < 0) {
            return Status(ErrorCodes::BadValue, "skip value is negative in count query");
        }

        request.setSkip(skip);
    } else if (cmdObj[kSkipField].ok()) {
        return Status(ErrorCodes::BadValue, "skip value is not a valid number");
    }

    // Hint
    if (Object == cmdObj[kHintField].type()) {
        request.setHint(cmdObj[kHintField].Obj());
    } else if (String == cmdObj[kHintField].type()) {
        const std::string hint = cmdObj.getStringField(kHintField);
        request.setHint(BSON("$hint" << hint));
    }

    return request;
}
Beispiel #24
0
void
calc_meta_graph() {
  BSONObj o, p, q;
  BSONObj emptyObj = BSONObj();

  if (metaGraph)
    delete metaGraph;
  metaGraph = new Graph();

  auto_ptr<DBClientCursor> cursor = connection->query("memprof_datasets.stdlib_groups", emptyObj);
  while( cursor->more() ) {
    o = cursor->next();
    int id = o.getIntField("_id");

    set<string> list;

    auto_ptr<DBClientCursor> rcursor = connection->query("memprof_datasets.stdlib_refs", BSON("_id" << BSON("$in" << o["members"])));
    while( rcursor->more() ) {
      p = rcursor->next();

      BSONObjIterator i( p["refs"].embeddedObject() );
      while ( i.more() ) {
        BSONElement e = i.next();
        list.insert(e.str());
      }
    }

    vector<string> list_v(list.begin(), list.end());
    set<int> refs;

    auto_ptr<DBClientCursor> gcursor = connection->query("memprof_datasets.stdlib_groups", BSON("members" << BSON("$in" << list_v)));
    while( gcursor->more() ) {
      q = gcursor->next();
      int r = q.getIntField("_id");
      if (r != id)
        refs.insert(r);
    }

    if (refs.size() > 0) {
      vector<int> refs_v(refs.begin(), refs.end());
      connection->update("memprof_datasets.stdlib_groups", BSON("_id" << id), BSON("$set" << BSON("refs" << refs_v)));

      (*metaGraph)[id] = refs;
    }
  }

  cout << endl << "  created w/ size: " << metaGraph->size();
}
    intrusive_ptr<DocumentSource> DocumentSourceUnwind::createFromBson(
            BSONElement elem,
            const intrusive_ptr<ExpressionContext> &pExpCtx) {
        /*
          The value of $unwind should just be a field path.
         */
        uassert(15981, str::stream() << "the " << unwindName <<
                " field path must be specified as a string",
                elem.type() == String);

        string prefixedPathString(elem.str());
        string pathString(Expression::removeFieldPrefix(prefixedPathString));
        intrusive_ptr<DocumentSourceUnwind> pUnwind(new DocumentSourceUnwind(pExpCtx));
        pUnwind->unwindPath(FieldPath(pathString));

        return pUnwind;
    }
Beispiel #26
0
static void do_each_child(string node, node_callback_with_data cb, void *data)
{
  BSONObj o;
  Query q = QUERY("_id" << node << "refs" << BSON("$exists" << true));

  auto_ptr<DBClientCursor> cursor = connection->query("memprof_datasets.stdlib_refs", q, 1);
  while( cursor->more() ) {
    o = cursor->next();

    BSONObjIterator i( o["refs"].embeddedObject() );
    while ( i.more() ) {
      BSONElement e = i.next();
      cb(e.str(), data);
    }

    break; // only one result
  }
}
Beispiel #27
0
// static
void QueryYield::yieldAllLocks(OperationContext* txn,
                               RecordFetcher* fetcher,
                               const std::string& planExecNS) {
    // Things have to happen here in a specific order:
    //   1) Tell the RecordFetcher to do any setup which needs to happen inside locks
    //   2) Release lock mgr locks
    //   3) Go to sleep
    //   4) Touch the record we're yielding on, if there is one (RecordFetcher::fetch)
    //   5) Reacquire lock mgr locks

    Locker* locker = txn->lockState();

    Locker::LockSnapshot snapshot;

    if (fetcher) {
        fetcher->setup();
    }

    // Nothing was unlocked, just return, yielding is pointless.
    if (!locker->saveLockStateAndUnlock(&snapshot)) {
        return;
    }

    // Top-level locks are freed, release any potential low-level (storage engine-specific
    // locks). If we are yielding, we are at a safe place to do so.
    txn->recoveryUnit()->abandonSnapshot();

    MONGO_FAIL_POINT_BLOCK(setYieldAllLocksWait, customWait) {
        const BSONObj& data = customWait.getData();
        BSONElement customWaitNS = data["namespace"];
        if (!customWaitNS || planExecNS == customWaitNS.str()) {
            sleepFor(stdx::chrono::milliseconds(data["waitForMillis"].numberInt()));
        }
    }

    // Track the number of yields in CurOp.
    CurOp::get(txn)->yielded();

    if (fetcher) {
        fetcher->fetch();
    }

    locker->restoreLockState(snapshot);
}
Beispiel #28
0
ShardStatus Shard::getStatus() const {
    BSONObj listDatabases;
    uassert(28589,
            str::stream() << "call to listDatabases on " << getConnString().toString()
                          << " failed: " << listDatabases,
            runCommand("admin", BSON("listDatabases" << 1), listDatabases));

    BSONElement totalSizeElem = listDatabases["totalSize"];
    uassert(28590, "totalSize field not found in listDatabases", totalSizeElem.isNumber());

    BSONObj serverStatus;
    uassert(28591,
            str::stream() << "call to serverStatus on " << getConnString().toString()
                          << " failed: " << serverStatus,
            runCommand("admin", BSON("serverStatus" << 1), serverStatus));

    BSONElement versionElement = serverStatus["version"];
    uassert(28599, "version field not found in serverStatus", versionElement.type() == String);

    return ShardStatus(totalSizeElem.numberLong(), versionElement.str());
}
Beispiel #29
0
    HashAccessMethod::HashAccessMethod(BtreeInMemoryState* btreeState)
        : BtreeBasedAccessMethod(btreeState) {

        const IndexDescriptor* descriptor = btreeState->descriptor();

        const string HASHED_INDEX_TYPE_IDENTIFIER = "hashed";

        //change these if single-field limitation lifted later
        uassert(16763, "Currently only single field hashed index supported." ,
                1 == descriptor->getNumFields());
        uassert(16764, "Currently hashed indexes cannot guarantee uniqueness. Use a regular index.",
                !descriptor->unique());

        // Default _seed to DEFAULT_HASH_SEED if "seed" is not included in the index spec
        // or if the value of "seed" is not a number

        // *** WARNING ***
        // Choosing non-default seeds will invalidate hashed sharding
        // Changing the seed default will break existing indexes and sharded collections

        if ( descriptor->getInfoElement( "seed" ).eoo() ) {
            _seed = BSONElementHasher::DEFAULT_HASH_SEED;
        }
        else {
            _seed = descriptor->getInfoElement("seed").numberInt();
        }

        //In case we have hashed indexes based on other hash functions in
        //the future, we store a hashVersion number. If hashVersion changes,
        // "makeSingleKey" will need to change accordingly.
        //Defaults to 0 if "hashVersion" is not included in the index spec
        //or if the value of "hashversion" is not a number
        _hashVersion = descriptor->getInfoElement("hashVersion").numberInt();

        //Get the hashfield name
        BSONElement firstElt = descriptor->keyPattern().firstElement();
        massert(16765, "error: no hashed index field",
                firstElt.str().compare(HASHED_INDEX_TYPE_IDENTIFIER) == 0);
        _hashedField = firstElt.fieldName();
    }
Beispiel #30
0
    HashedIndexType::HashedIndexType( const IndexPlugin* plugin , const IndexSpec* spec ) :
            IndexType( plugin , spec ) , _keyPattern( spec->keyPattern ) {

        //change these if single-field limitation lifted later
        uassert( 16241 , "Currently only single field hashed index supported." ,
                _keyPattern.toBSON().nFields() == 1 );
        uassert( 16242 , "Currently hashed indexes cannot guarantee uniqueness. Use a regular index." ,
                ! (spec->info).getField("unique").booleanSafe() );

        //Default _seed to 0 if "seed" is not included in the index spec
        //or if the value of "seed" is not a number
        _seed = (spec->info).getField("seed").numberInt();

        //Default _isSparse to false if "sparse" is not included in the index spec
        //or if the value of "sparse" is not a boolean
        _isSparse = (spec->info).getField("sparse").booleanSafe();

        //In case we have hashed indexes based on other hash functions in
        //the future, we store a hashVersion number. If hashVersion changes,
        // "makeSingleKey" will need to change accordingly.
        //Defaults to 0 if "hashVersion" is not included in the index spec
        //or if the value of "hashversion" is not a number
        _hashVersion = (spec->info).getField("hashVersion").numberInt();

        //Get the hashfield name
        BSONElement firstElt = spec->keyPattern.firstElement();
        massert( 16243 , "error: no hashed index field" ,
                firstElt.str().compare( HASHED_INDEX_TYPE_IDENTIFIER ) == 0 );
        _hashedField = firstElt.fieldName();

        // Explicit null valued fields and missing fields are both represented in hashed indexes
        // using the hash value of the null BSONElement.  This is partly for historical reasons
        // (hash of null was used in the initial release of hashed indexes and changing would alter
        // the data format).  Additionally, in certain places the hashed index code and the index
        // bound calculation code assume null and missing are indexed identically.
        BSONObj nullObj = BSON( "" << BSONNULL );
        _missingKey = BSON( "" << makeSingleKey( nullObj.firstElement(), _seed, _hashVersion ) );
    }