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); }
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(); }
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(); }
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); } }
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(); }
// 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(); }
bool KVCatalog::FeatureTracker::isFeatureDocument(BSONObj obj) { BSONElement firstElem = obj.firstElement(); if (firstElem.fieldNameStringData() == kIsFeatureDocumentFieldName) { return firstElem.booleanSafe(); } return false; }
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(); }
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()}; }
/** * 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; }
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(); }
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(); }
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(); }
// 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; }