Beispiel #1
0
Status validateStorageOptions(const BSONObj& storageEngineOptions,
                              stdx::function<Status (const StorageEngine::Factory* const, const BSONObj&)> validateFunc) {

    BSONObjIterator storageIt(storageEngineOptions);
    while (storageIt.more()) {
        BSONElement storageElement = storageIt.next();
        StringData storageEngineName = storageElement.fieldNameStringData();
        if (storageElement.type() != mongo::Object) {
            return Status(ErrorCodes::BadValue, str::stream()
                          << "'storageEngine." << storageElement.fieldNameStringData()
                          << "' has to be an embedded document.");
        }

        boost::scoped_ptr<StorageFactoriesIterator> sfi(getGlobalServiceContext()->
                makeStorageFactoriesIterator());
        invariant(sfi);
        bool found = false;
        while (sfi->more()) {
            const StorageEngine::Factory* const& factory = sfi->next();
            if (storageEngineName != factory->getCanonicalName()) {
                continue;
            }
            Status status = validateFunc(factory, storageElement.Obj());
            if ( !status.isOK() ) {
                return status;
            }
            found = true;
        }
        if (!found) {
            return Status(ErrorCodes::InvalidOptions, str::stream() << storageEngineName <<
                          " is not a registered storage engine for this server");
        }
    }
    return Status::OK();
}
/**
 * Currently the allowable shard keys are either
 * i) a hashed single field, e.g. { a : "hashed" }, or
 * ii) a compound list of ascending, potentially-nested field paths, e.g. { a : 1 , b.c : 1 }
 */
static vector<FieldRef*> parseShardKeyPattern(const BSONObj& keyPattern) {
    OwnedPointerVector<FieldRef> parsedPaths;
    static const vector<FieldRef*> empty;

    BSONObjIterator patternIt(keyPattern);
    while (patternIt.more()) {
        BSONElement patternEl = patternIt.next();
        parsedPaths.push_back(new FieldRef(patternEl.fieldNameStringData()));
        const FieldRef& patternPath = *parsedPaths.back();

        // Empty path
        if (patternPath.numParts() == 0)
            return empty;

        // Extra "." in path?
        if (patternPath.dottedField() != patternEl.fieldNameStringData())
            return empty;

        // Empty parts of the path, ".."?
        for (size_t i = 0; i < patternPath.numParts(); ++i) {
            if (patternPath.getPart(i).size() == 0)
                return empty;
        }

        // Numeric and ascending (1.0), or "hashed" and single field
        if (!patternEl.isNumber()) {
            if (keyPattern.nFields() != 1 || !isHashedPatternEl(patternEl))
                return empty;
        } else if (patternEl.numberInt() != 1) {
            return empty;
        }
    }

    return parsedPaths.release();
}
StatusWith<std::vector<LogComponentSetting>> parseLogComponentSettings(const BSONObj& settings) {
    typedef std::vector<LogComponentSetting> Result;

    std::vector<LogComponentSetting> levelsToSet;
    std::vector<BSONObjIterator> iterators;

    LogComponent parentComponent = LogComponent::kDefault;
    BSONObjIterator iter(settings);

    while (iter.moreWithEOO()) {
        BSONElement elem = iter.next();
        if (elem.eoo()) {
            if (!iterators.empty()) {
                iter = iterators.back();
                iterators.pop_back();
                parentComponent = parentComponent.parent();
            }
            continue;
        }
        if (elem.fieldNameStringData() == "verbosity") {
            if (!elem.isNumber()) {
                return StatusWith<Result>(ErrorCodes::BadValue,
                                          str::stream() << "Expected "
                                                        << parentComponent.getDottedName()
                                                        << ".verbosity to be a number, but found "
                                                        << typeName(elem.type()));
            }
            levelsToSet.push_back((LogComponentSetting(parentComponent, elem.numberInt())));
            continue;
        }
        const StringData shortName = elem.fieldNameStringData();
        const LogComponent curr = _getComponentForShortName(shortName);

        if (curr == LogComponent::kNumLogComponents || curr.parent() != parentComponent) {
            return StatusWith<Result>(
                ErrorCodes::BadValue,
                str::stream() << "Invalid component name " << parentComponent.getDottedName() << "."
                              << shortName);
        }
        if (elem.isNumber()) {
            levelsToSet.push_back(LogComponentSetting(curr, elem.numberInt()));
            continue;
        }
        if (elem.type() != Object) {
            return StatusWith<Result>(ErrorCodes::BadValue,
                                      str::stream() << "Invalid type " << typeName(elem.type())
                                                    << "for component "
                                                    << parentComponent.getDottedName()
                                                    << "."
                                                    << shortName);
        }
        iterators.push_back(iter);
        parentComponent = curr;
        iter = BSONObjIterator(elem.Obj());
    }

    // Done walking settings
    return StatusWith<Result>(levelsToSet);
}
Beispiel #4
0
    Status UpdateDriver::createFromQuery(const BSONObj& query, mutablebson::Document& doc) {
        BSONObjIteratorSorted i(query);
        while (i.more()) {
            BSONElement e = i.next();
            // TODO: get this logic/exclude-list from the query system?
            if (e.fieldName()[0] == '$' || e.fieldNameStringData() == "_id")
                continue;


            if (e.type() == Object && e.embeddedObject().firstElementFieldName()[0] == '$') {
                // we have something like { x : { $gt : 5 } }
                // this can be a query piece
                // or can be a dbref or something

                int op = e.embeddedObject().firstElement().getGtLtOp();
                if (op > 0) {
                    // This means this is a $gt type filter, so don't make it part of the new
                    // object.
                    continue;
                }

                if (mongoutils::str::equals(e.embeddedObject().firstElement().fieldName(),
                                              "$not")) {
                    // A $not filter operator is not detected in getGtLtOp() and should not
                    // become part of the new object.
                    continue;
                }
            }

            // Add to the field to doc after expanding and checking for conflicts.
            FieldRef elemName;
            const StringData& elemNameSD(e.fieldNameStringData());
            elemName.parse(elemNameSD);

            size_t pos;
            mutablebson::Element* elemFound = NULL;

            Status status = pathsupport::findLongestPrefix(elemName, doc.root(), &pos, elemFound);
            // Not NonExistentPath, of OK, return
            if (!(status.code() == ErrorCodes::NonExistentPath || status.isOK()))
                return status;

            status = pathsupport::createPathAt(elemName,
                                               0,
                                               doc.root(),
                                               doc.makeElementWithNewFieldName(
                                                       elemName.getPart(elemName.numParts()-1),
                                                       e));
            if (!status.isOK())
                return status;
        }
        return Status::OK();
    }
Beispiel #5
0
Status ClientMetadata::validateOperatingSystemDocument(const BSONObj& doc) {
    bool foundType = false;

    BSONObjIterator i(doc);
    while (i.more()) {
        BSONElement e = i.next();
        StringData name = e.fieldNameStringData();

        if (name == kType) {
            if (e.type() != String) {
                return Status(
                    ErrorCodes::TypeMismatch,
                    str::stream() << "The '" << kOperatingSystem << "." << kType
                                  << "' field must be a string in the client metadata document");
            }

            foundType = true;
        }
    }

    if (foundType == false) {
        return Status(ErrorCodes::ClientMetadataMissingField,
                      str::stream() << "Missing required field '" << kOperatingSystem << "."
                                    << kType
                                    << "' in the client metadata document");
    }

    return Status::OK();
}
Beispiel #6
0
void BSONInfo::enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties) {
    auto holder = getHolder(obj);

    if (!holder)
        return;

    BSONObjIterator i(holder->_obj);

    ObjectWrapper o(cx, obj);
    JS::RootedValue val(cx);
    JS::RootedId id(cx);

    while (i.more()) {
        BSONElement e = i.next();

        // TODO: when we get heterogenous set lookup, switch to StringData
        // rather than involving the temporary string
        if (holder->_removed.count(e.fieldName()))
            continue;

        ValueReader(cx, &val).fromStringData(e.fieldNameStringData());

        if (!JS_ValueToId(cx, val, &id))
            uasserted(ErrorCodes::JSInterpreterFailure, "Failed to invoke JS_ValueToId");

        properties.append(id);
    }
}
Beispiel #7
0
    void run() {
        const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
        OperationContext& opCtx = *opCtxPtr;
        dbtests::WriteContextForTests ctx(&opCtx, _nss.ns());

        int numFinishedIndexesStart = _catalog->numIndexesReady(&opCtx);

        dbtests::createIndex(&opCtx, _nss.ns(), BSON("x" << 1)).transitional_ignore();
        dbtests::createIndex(&opCtx, _nss.ns(), BSON("y" << 1)).transitional_ignore();

        ASSERT_TRUE(_catalog->numIndexesReady(&opCtx) == numFinishedIndexesStart + 2);

        std::unique_ptr<IndexCatalog::IndexIterator> ii = _catalog->getIndexIterator(&opCtx, false);
        int indexesIterated = 0;
        bool foundIndex = false;
        while (ii->more()) {
            auto indexDesc = ii->next()->descriptor();
            indexesIterated++;
            BSONObjIterator boit(indexDesc->infoObj());
            while (boit.more() && !foundIndex) {
                BSONElement e = boit.next();
                if (e.fieldNameStringData() == "name" && e.valueStringDataSafe() == "y_1") {
                    foundIndex = true;
                    break;
                }
            }
        }

        ASSERT_TRUE(indexesIterated == _catalog->numIndexesReady(&opCtx));
        ASSERT_TRUE(foundIndex);
    }
    Status ModifierObjectReplace::init(const BSONElement& modExpr, const Options& opts) {

        if (modExpr.type() != Object) {
            // Impossible, really since the caller check this already...
            return Status(ErrorCodes::BadValue,
                          str::stream() << "object replace expects full object but type was "
                                        << modExpr.type());
        }

        if (opts.enforceOkForStorage) {
            Status s = modExpr.embeddedObject().storageValid();
            if (!s.isOK())
                return s;
        } else {
            // storageValid checks for $-prefixed field names, so only run if we didn't do that.
            BSONObjIterator it(modExpr.embeddedObject());
            while (it.more()) {
                BSONElement elem = it.next();
                if (*elem.fieldName() == '$') {
                    return Status(ErrorCodes::BadValue,
                                  str::stream() << "A replace document can't"
                                                   " contain update modifiers: "
                                                << elem.fieldNameStringData());
                }
            }
        }

        // We make a copy of the object here because the update driver does not guarantees, in
        // the case of object replacement, that the modExpr is going to outlive this mod.
        _val = modExpr.embeddedObject().getOwned();
        fixupTimestamps(_val);

        return Status::OK();
    }
Beispiel #9
0
// static
Status WiredTigerUtil::checkTableCreationOptions(const BSONElement& configElem) {
    invariant(configElem.fieldNameStringData() == "configString");

    if (configElem.type() != String) {
        return {ErrorCodes::TypeMismatch, "'configString' must be a string."};
    }

    std::vector<std::string> errors;
    ErrorAccumulator eventHandler(&errors);

    StringData config = configElem.valueStringData();
    // Do NOT allow embedded null characters
    if (config.size() != strlen(config.rawData())) {
        return {ErrorCodes::FailedToParse, "malformed 'configString' value."};
    }

    Status status = wtRCToStatus(
        wiredtiger_config_validate(nullptr, &eventHandler, "WT_SESSION.create", config.rawData()));
    if (!status.isOK()) {
        StringBuilder errorMsg;
        errorMsg << status.reason();
        for (std::string error : errors) {
            errorMsg << ". " << error;
        }
        errorMsg << ".";
        return status.withReason(errorMsg.stringData());
    }
    return Status::OK();
}
Beispiel #10
0
bool KVCatalog::FeatureTracker::isFeatureDocument(BSONObj obj) {
    BSONElement firstElem = obj.firstElement();
    if (firstElem.fieldNameStringData() == kIsFeatureDocumentFieldName) {
        return firstElem.booleanSafe();
    }
    return false;
}
Beispiel #11
0
    Document DocumentSource::documentFromBsonWithDeps(const BSONObj& bson,
                                                      const ParsedDeps& neededFields) {
        MutableDocument md(neededFields.size());

        BSONObjIterator it(bson);
        while (it.more()) {
            BSONElement bsonElement (it.next());
            StringData fieldName = bsonElement.fieldNameStringData();
            Value isNeeded = neededFields[fieldName];

            if (isNeeded.missing())
                continue;

            if (isNeeded.getType() == Bool) {
                md.addField(fieldName, Value(bsonElement));
                continue;
            }

            dassert(isNeeded.getType() == Object);

            if (bsonElement.type() == Object) {
                Document sub = documentFromBsonWithDeps(bsonElement.embeddedObject(),
                                                        isNeeded.getDocument());
                md.addField(fieldName, Value(sub));
            }

            if (bsonElement.type() == Array) {
                md.addField(fieldName, arrayHelper(bsonElement.embeddedObject(),
                                                   isNeeded.getDocument()));
            }
        }

        return md.freeze();
    }
Beispiel #12
0
StatusWith<StringData> ClientMetadata::parseApplicationDocument(const BSONObj& doc) {
    BSONObjIterator i(doc);

    while (i.more()) {
        BSONElement e = i.next();
        StringData name = e.fieldNameStringData();

        // Name is the only required field, and any other fields are simply ignored.
        if (name == kName) {

            if (e.type() != String) {
                return {
                    ErrorCodes::TypeMismatch,
                    str::stream() << "The '" << kApplication << "." << kName
                                  << "' field must be a string in the client metadata document"};
            }

            StringData value = e.checkAndGetStringData();

            if (value.size() > kMaxApplicationNameByteLength) {
                return {ErrorCodes::ClientMetadataAppNameTooLarge,
                        str::stream() << "The '" << kApplication << "." << kName
                                      << "' field must be less then or equal to "
                                      << kMaxApplicationNameByteLength
                                      << " bytes in the client metadata document"};
            }

            return {std::move(value)};
        }
    }

    return {StringData()};
}
Beispiel #13
0
    /**
     * Encodes parsed projection into cache key.
     * Does a simple toString() on each projected field
     * in the BSON object.
     * Orders the encoded elements in the projection by field name.
     * This handles all the special projection types ($meta, $elemMatch, etc.)
     */
    void PlanCache::encodeKeyForProj(const BSONObj& projObj, StringBuilder* keyBuilder) const {
        if (projObj.isEmpty()) {
            return;
        }

        *keyBuilder << kEncodeProjectionSection;

        // Sorts the BSON elements by field name using a map.
        std::map<StringData, BSONElement> elements;

        BSONObjIterator it(projObj);
        while (it.more()) {
            BSONElement elt = it.next();
            StringData fieldName = elt.fieldNameStringData();
            elements[fieldName] = elt;
        }

        // Read elements in order of field name
        for (std::map<StringData, BSONElement>::const_iterator i = elements.begin();
             i != elements.end(); ++i) {
            const BSONElement& elt = (*i).second;
            // BSONElement::toString() arguments
            // includeFieldName - skip field name (appending after toString() result). false.
            // full: choose less verbose representation of child/data values. false.
            encodeUserString(elt.toString(false, false), keyBuilder);
            encodeUserString(elt.fieldName(), keyBuilder);
        }
    }
BSONObj ShardKeyPattern::normalizeShardKey(const BSONObj& shardKey) const {
    // Shard keys are always of the form: { 'nested.path' : value, 'nested.path2' : value }
    // and in the same order as the key pattern

    if (!isValid())
        return BSONObj();

    // We want to return an empty key if users pass us something that's not a shard key
    if (shardKey.nFields() > _keyPattern.toBSON().nFields())
        return BSONObj();

    BSONObjBuilder keyBuilder;
    BSONObjIterator patternIt(_keyPattern.toBSON());
    while (patternIt.more()) {
        BSONElement patternEl = patternIt.next();

        BSONElement keyEl = shardKey[patternEl.fieldNameStringData()];

        if (!isShardKeyElement(keyEl, true))
            return BSONObj();

        keyBuilder.appendAs(keyEl, patternEl.fieldName());
    }

    dassert(isShardKey(keyBuilder.asTempObj()));
    return keyBuilder.obj();
}
AccumulationStatement AccumulationStatement::parseAccumulationStatement(
    const boost::intrusive_ptr<ExpressionContext>& expCtx,
    const BSONElement& elem,
    const VariablesParseState& vps) {
    auto fieldName = elem.fieldNameStringData();
    uassert(40234,
            str::stream() << "The field '" << fieldName << "' must be an accumulator object",
            elem.type() == BSONType::Object &&
                elem.embeddedObject().firstElementFieldName()[0] == '$');

    uassert(40235,
            str::stream() << "The field name '" << fieldName << "' cannot contain '.'",
            fieldName.find('.') == string::npos);

    uassert(40236,
            str::stream() << "The field name '" << fieldName << "' cannot be an operator name",
            fieldName[0] != '$');

    uassert(40238,
            str::stream() << "The field '" << fieldName << "' must specify one accumulator",
            elem.Obj().nFields() == 1);

    auto specElem = elem.Obj().firstElement();
    auto accName = specElem.fieldNameStringData();
    uassert(40237,
            str::stream() << "The " << accName << " accumulator is a unary operator",
            specElem.type() != BSONType::Array);

    return {fieldName.toString(),
            Expression::parseOperand(expCtx, specElem, vps),
            AccumulationStatement::getFactory(accName)};
}
BSONObj  //
    ShardKeyPattern::extractShardKeyFromMatchable(const MatchableDocument& matchable) const {
    if (!isValid())
        return BSONObj();

    BSONObjBuilder keyBuilder;

    BSONObjIterator patternIt(_keyPattern.toBSON());
    while (patternIt.more()) {
        BSONElement patternEl = patternIt.next();
        BSONElement matchEl =
            extractKeyElementFromMatchable(matchable, patternEl.fieldNameStringData());

        if (!isShardKeyElement(matchEl, true))
            return BSONObj();

        if (isHashedPatternEl(patternEl)) {
            keyBuilder.append(
                patternEl.fieldName(),
                BSONElementHasher::hash64(matchEl, BSONElementHasher::DEFAULT_HASH_SEED));
        } else {
            // NOTE: The matched element may *not* have the same field name as the path -
            // index keys don't contain field names, for example
            keyBuilder.appendAs(matchEl, patternEl.fieldName());
        }
    }

    dassert(isShardKey(keyBuilder.asTempObj()));
    return keyBuilder.obj();
}
bool BatchedInsertRequest::parseBSON(StringData dbName, const BSONObj& source, string* errMsg) {
    clear();

    std::string dummy;
    if (!errMsg)
        errMsg = &dummy;

    BSONObjIterator sourceIt(source);

    while (sourceIt.more()) {
        BSONElement sourceEl = sourceIt.next();

        if (collName() == sourceEl.fieldName()) {
            std::string temp;
            FieldParser::FieldState fieldState =
                FieldParser::extract(sourceEl, collName, &temp, errMsg);
            if (fieldState == FieldParser::FIELD_INVALID)
                return false;
            _ns = NamespaceString(dbName, temp);
            uassert(ErrorCodes::InvalidNamespace,
                    str::stream() << "Invalid namespace: " << _ns.ns(),
                    _ns.isValid());
            _isNSSet = fieldState == FieldParser::FIELD_SET;
        } else if (documents() == sourceEl.fieldName()) {
            FieldParser::FieldState fieldState =
                FieldParser::extract(sourceEl, documents, &_documents, errMsg);
            if (fieldState == FieldParser::FIELD_INVALID)
                return false;
            _isDocumentsSet = fieldState == FieldParser::FIELD_SET;
            if (_documents.size() >= 1)
                extractIndexNSS(_documents.at(0), &_targetNSS);
        } else if (writeConcern() == sourceEl.fieldName()) {
            FieldParser::FieldState fieldState =
                FieldParser::extract(sourceEl, writeConcern, &_writeConcern, errMsg);
            if (fieldState == FieldParser::FIELD_INVALID)
                return false;
            _isWriteConcernSet = fieldState == FieldParser::FIELD_SET;
        } else if (ordered() == sourceEl.fieldName()) {
            FieldParser::FieldState fieldState =
                FieldParser::extract(sourceEl, ordered, &_ordered, errMsg);
            if (fieldState == FieldParser::FIELD_INVALID)
                return false;
            _isOrderedSet = fieldState == FieldParser::FIELD_SET;
        } else if (bypassDocumentValidationCommandOption() == sourceEl.fieldNameStringData()) {
            _shouldBypassValidation = sourceEl.trueValue();
        } else if (sourceEl.fieldName()[0] != '$') {
            std::initializer_list<StringData> ignoredFields = {"maxTimeMS", "shardVersion"};
            if (std::find(ignoredFields.begin(), ignoredFields.end(), sourceEl.fieldName()) ==
                ignoredFields.end()) {
                *errMsg = str::stream() << "Unknown option to insert command: "
                                        << sourceEl.fieldName();
                return false;
            }
        }
    }

    return true;
}
Beispiel #18
0
    ProjectionStage::ProjectionStage(const ProjectionStageParams& params,
                                     WorkingSet* ws,
                                     PlanStage* child)
        : _ws(ws),
          _child(child),
          _commonStats(kStageType),
          _projImpl(params.projImpl) {

        _projObj = params.projObj;

        if (ProjectionStageParams::NO_FAST_PATH == _projImpl) {
            _exec.reset(new ProjectionExec(params.projObj, 
                                           params.fullExpression,
                                           *params.whereCallback));
        }
        else {
            // We shouldn't need the full expression if we're fast-pathing.
            invariant(NULL == params.fullExpression);

            // Sanity-check the input.
            invariant(_projObj.isOwned());
            invariant(!_projObj.isEmpty());

            // Figure out what fields are in the projection.
            getSimpleInclusionFields(_projObj, &_includedFields);

            // If we're pulling data out of one index we can pre-compute the indices of the fields
            // in the key that we pull data from and avoid looking up the field name each time.
            if (ProjectionStageParams::COVERED_ONE_INDEX == params.projImpl) {
                // Sanity-check.
                _coveredKeyObj = params.coveredKeyObj;
                invariant(_coveredKeyObj.isOwned());

                BSONObjIterator kpIt(_coveredKeyObj);
                while (kpIt.more()) {
                    BSONElement elt = kpIt.next();
                    unordered_set<StringData, StringData::Hasher>::iterator fieldIt;
                    fieldIt = _includedFields.find(elt.fieldNameStringData());

                    if (_includedFields.end() == fieldIt) {
                        // Push an unused value on the back to keep _includeKey and _keyFieldNames
                        // in sync.
                        _keyFieldNames.push_back(StringData());
                        _includeKey.push_back(false);
                    }
                    else {
                        // If we are including this key field store its field name.
                        _keyFieldNames.push_back(*fieldIt);
                        _includeKey.push_back(true);
                    }
                }
            }
            else {
                invariant(ProjectionStageParams::SIMPLE_DOC == params.projImpl);
            }
        }
    }
Status ReadConcernArgs::initialize(const BSONElement& readConcernElem) {
    invariant(!_opTime && !_level);  // only legal to call on uninitialized object.

    if (readConcernElem.eoo()) {
        return Status::OK();
    }

    dassert(readConcernElem.fieldNameStringData() == kReadConcernFieldName);

    if (readConcernElem.type() != Object) {
        return Status(ErrorCodes::FailedToParse,
                      str::stream() << kReadConcernFieldName << " field should be an object");
    }

    BSONObj readConcernObj = readConcernElem.Obj();
    for (auto&& field : readConcernObj) {
        auto fieldName = field.fieldNameStringData();
        if (fieldName == kAfterOpTimeFieldName) {
            OpTime opTime;
            // TODO pass field in rather than scanning again.
            auto opTimeStatus =
                bsonExtractOpTimeField(readConcernObj, kAfterOpTimeFieldName, &opTime);
            if (!opTimeStatus.isOK()) {
                return opTimeStatus;
            }
            _opTime = opTime;
        } else if (fieldName == kLevelFieldName) {
            std::string levelString;
            // TODO pass field in rather than scanning again.
            auto readCommittedStatus =
                bsonExtractStringField(readConcernObj, kLevelFieldName, &levelString);
            if (!readCommittedStatus.isOK()) {
                return readCommittedStatus;
            }
            if (levelString == kLocalReadConcernStr) {
                _level = ReadConcernLevel::kLocalReadConcern;
            } else if (levelString == kMajorityReadConcernStr) {
                _level = ReadConcernLevel::kMajorityReadConcern;
            } else if (levelString == kLinearizableReadConcernStr) {
                _level = ReadConcernLevel::kLinearizableReadConcern;
            } else {
                return Status(
                    ErrorCodes::FailedToParse,
                    str::stream() << kReadConcernFieldName << '.' << kLevelFieldName
                                  << " must be either 'local', 'majority' or 'linearizable'");
            }
        } else {
            return Status(ErrorCodes::InvalidOptions,
                          str::stream() << "Unrecognized option in " << kReadConcernFieldName
                                        << ": "
                                        << fieldName);
        }
    }

    return Status::OK();
}
Beispiel #20
0
 string Command::parseNsFullyQualified(const string& dbname, const BSONObj& cmdObj) const {
     BSONElement first = cmdObj.firstElement();
     uassert(17005,
             mongoutils::str::stream() << "Main argument to " << first.fieldNameStringData() <<
                     " must be a fully qualified namespace string.  Found: " <<
                     first.toString(false),
             first.type() == mongo::String &&
             NamespaceString::validCollectionComponent(first.valuestr()));
     return first.String();
 }
Beispiel #21
0
    Status ProjectionStage::transform(WorkingSetMember* member) {
        // The default no-fast-path case.
        if (ProjectionStageParams::NO_FAST_PATH == _projImpl) {
            return _exec->transform(member);
        }

        BSONObjBuilder bob;

        // Note that even if our fast path analysis is bug-free something that is
        // covered might be invalidated and just be an obj.  In this case we just go
        // through the SIMPLE_DOC path which is still correct if the covered data
        // is not available.
        //
        // SIMPLE_DOC implies that we expect an object so it's kind of redundant.
        if ((ProjectionStageParams::SIMPLE_DOC == _projImpl) || member->hasObj()) {
            // If we got here because of SIMPLE_DOC the planner shouldn't have messed up.
            invariant(member->hasObj());

            // Look at every field in the source document and see if we're including it.
            BSONObjIterator inputIt(member->obj);
            while (inputIt.more()) {
                BSONElement elt = inputIt.next();
                unordered_set<StringData, StringData::Hasher>::iterator fieldIt;
                fieldIt = _includedFields.find(elt.fieldNameStringData());
                if (_includedFields.end() != fieldIt) {
                    // If so, add it to the builder.
                    bob.append(elt);
                }
            }
        }
        else {
            invariant(ProjectionStageParams::COVERED_ONE_INDEX == _projImpl);
            // We're pulling data out of the key.
            invariant(1 == member->keyData.size());
            size_t keyIndex = 0;

            // Look at every key element...
            BSONObjIterator keyIterator(member->keyData[0].keyData);
            while (keyIterator.more()) {
                BSONElement elt = keyIterator.next();
                // If we're supposed to include it...
                if (_includeKey[keyIndex]) {
                    // Do so.
                    bob.appendAs(elt, _keyFieldNames[keyIndex]);
                }
                ++keyIndex;
            }
        }

        member->state = WorkingSetMember::OWNED_OBJ;
        member->keyData.clear();
        member->loc = DiskLoc();
        member->obj = bob.obj();
        return Status::OK();
    }
void CollectionMetadata::fillKeyPatternFields() {
    // Parse the shard keys into the states 'keys' and 'keySet' members.
    BSONObjIterator patternIter = _keyPattern.begin();
    while (patternIter.more()) {
        BSONElement current = patternIter.next();

        _keyFields.mutableVector().push_back(new FieldRef);
        FieldRef* const newFieldRef = _keyFields.mutableVector().back();
        newFieldRef->parse(current.fieldNameStringData());
    }
}
Status ModifierObjectReplace::apply() const {
    dassert(!_preparedState->noOp);

    // Remove the contents of the provided doc.
    mutablebson::Document& doc = _preparedState->doc;
    mutablebson::Element current = doc.root().leftChild();
    mutablebson::Element srcIdElement = doc.end();
    while (current.ok()) {
        mutablebson::Element toRemove = current;
        current = current.rightSibling();

        // Skip _id field element -- it should not change
        if (toRemove.getFieldName() == idFieldName) {
            srcIdElement = toRemove;
            continue;
        }

        Status status = toRemove.remove();
        if (!status.isOK()) {
            return status;
        }
    }

    // Insert the provided contents instead.
    BSONElement dstIdElement;
    BSONObjIterator it(_val);
    while (it.more()) {
        BSONElement elem = it.next();
        if (elem.fieldNameStringData() == idFieldName) {
            dstIdElement = elem;

            // Do not duplicate _id field
            if (srcIdElement.ok()) {
                if (srcIdElement.compareWithBSONElement(dstIdElement, nullptr, true) != 0) {
                    return Status(ErrorCodes::ImmutableField,
                                  str::stream() << "The _id field cannot be changed from {"
                                                << srcIdElement.toString()
                                                << "} to {"
                                                << dstIdElement.toString()
                                                << "}.");
                }
                continue;
            }
        }

        Status status = doc.root().appendElement(elem);
        if (!status.isOK()) {
            return status;
        }
    }

    return Status::OK();
}
void BSONCollectionCatalogEntry::IndexMetaData::updateTTLSetting(long long newExpireSeconds) {
    BSONObjBuilder b;
    for (BSONObjIterator bi(spec); bi.more();) {
        BSONElement e = bi.next();
        if (e.fieldNameStringData() == "expireAfterSeconds") {
            continue;
        }
        b.append(e);
    }

    b.append("expireAfterSeconds", newExpireSeconds);
    spec = b.obj();
}
Beispiel #25
0
// static
void ProjectionStage::transformSimpleInclusion(const BSONObj& in,
                                               const FieldSet& includedFields,
                                               BSONObjBuilder& bob) {
    // Look at every field in the source document and see if we're including it.
    BSONObjIterator inputIt(in);
    while (inputIt.more()) {
        BSONElement elt = inputIt.next();
        auto fieldIt = includedFields.find(elt.fieldNameStringData());
        if (includedFields.end() != fieldIt) {
            // If so, add it to the builder.
            bob.append(elt);
        }
    }
}
int BSONElement::woCompare(const BSONElement& elem,
                           ComparisonRulesSet rules,
                           const StringData::ComparatorInterface* comparator) const {
    if (type() != elem.type()) {
        int lt = (int)canonicalType();
        int rt = (int)elem.canonicalType();
        if (int diff = lt - rt)
            return diff;
    }
    if (rules & ComparisonRules::kConsiderFieldName) {
        if (int diff = fieldNameStringData().compare(elem.fieldNameStringData()))
            return diff;
    }
    return compareElements(*this, elem, rules, comparator);
}
intrusive_ptr<DocumentSource> DocumentSource::parse(const intrusive_ptr<ExpressionContext> expCtx,
                                                    BSONObj stageObj) {
    uassert(16435,
            "A pipeline stage specification object must contain exactly one field.",
            stageObj.nFields() == 1);
    BSONElement stageSpec = stageObj.firstElement();
    auto stageName = stageSpec.fieldNameStringData();

    // Get the registered parser and call that.
    auto it = parserMap.find(stageName);
    uassert(16436,
            str::stream() << "Unrecognized pipeline stage name: '" << stageName << "'",
            it != parserMap.end());
    return it->second(stageSpec, expCtx);
}
 // static
 StatusWith<int> LiteParsedQuery::parseMaxTimeMS(const BSONElement& maxTimeMSElt) {
     if (!maxTimeMSElt.eoo() && !maxTimeMSElt.isNumber()) {
         return StatusWith<int>(ErrorCodes::BadValue,
                                (StringBuilder()
                                    << maxTimeMSElt.fieldNameStringData()
                                    << " must be a number").str());
     }
     long long maxTimeMSLongLong = maxTimeMSElt.safeNumberLong(); // returns 0 on EOO
     if (maxTimeMSLongLong < 0 || maxTimeMSLongLong > INT_MAX) {
         return StatusWith<int>(ErrorCodes::BadValue,
                                (StringBuilder()
                                    << maxTimeMSElt.fieldNameStringData()
                                    << " is out of range").str());
     }
     double maxTimeMSDouble = maxTimeMSElt.numberDouble();
     if (maxTimeMSElt.type() == mongo::NumberDouble
         && floor(maxTimeMSDouble) != maxTimeMSDouble) {
         return StatusWith<int>(ErrorCodes::BadValue,
                                (StringBuilder()
                                    << maxTimeMSElt.fieldNameStringData()
                                    << " has non-integral value").str());
     }
     return StatusWith<int>(static_cast<int>(maxTimeMSLongLong));
 }
std::unique_ptr<LiteParsedDocumentSource> LiteParsedDocumentSource::parse(
    const AggregationRequest& request, const BSONObj& spec) {
    uassert(40323,
            "A pipeline stage specification object must contain exactly one field.",
            spec.nFields() == 1);
    BSONElement specElem = spec.firstElement();

    auto stageName = specElem.fieldNameStringData();
    auto it = parserMap.find(stageName);

    uassert(40324,
            str::stream() << "Unrecognized pipeline stage name: '" << stageName << "'",
            it != parserMap.end());

    return it->second(request, specElem);
}
bool ShardKeyPattern::isShardKey(const BSONObj& shardKey) const {
    // Shard keys are always of the form: { 'nested.path' : value, 'nested.path2' : value }

    if (!isValid())
        return false;

    BSONObjIterator patternIt(_keyPattern.toBSON());
    while (patternIt.more()) {
        BSONElement patternEl = patternIt.next();

        BSONElement keyEl = shardKey[patternEl.fieldNameStringData()];
        if (!isShardKeyElement(keyEl, true))
            return false;
    }

    return true;
}