Status _initializeUserRolesFromV1RolesArray(User* user, const BSONElement& rolesElement, const StringData& dbname) { static const char privilegesTypeMismatchMessage[] = "Roles in V1 user documents must be enumerated in an array of strings."; 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); user->addRole(RoleName(roleElement.String(), dbname)); } return Status::OK(); }
void DBConfig::unserialize(const BSONObj& from) { _name = from.getStringField("name"); _partitioned = from.getBoolField("partitioned"); _primary = from.getStringField("primary"); _sharded.clear(); BSONObj sharded = from.getObjectField( "sharded" ); if ( ! sharded.isEmpty() ) { BSONObjIterator i(sharded); while ( i.more() ) { BSONElement e = i.next(); if ( e.eoo() ) break; uassert( "shared things have to be objects" , e.type() == Object ); _sharded[e.fieldName()] = e.embeddedObject(); } } }
bool GeoNearExpression::parseLegacyQuery(const BSONObj& obj) { bool hasGeometry = false; // First, try legacy near, e.g.: // t.find({ loc : { $nearSphere: [0,0], $minDistance: 1, $maxDistance: 3 }}) // t.find({ loc : { $nearSphere: [0,0] }}) // t.find({ loc : { $near : [0, 0, 1] } }); // t.find({ loc : { $near: { someGeoJSONPoint}}) // t.find({ loc : { $geoNear: { someGeoJSONPoint}}) BSONObjIterator it(obj); while (it.more()) { BSONElement e = it.next(); if (equals(e.fieldName(), "$near") || equals(e.fieldName(), "$geoNear") || equals(e.fieldName(), "$nearSphere")) { if (!e.isABSONObj()) { return false; } BSONObj embeddedObj = e.embeddedObject(); if (GeoParser::parseQueryPoint(e, centroid.get()).isOK() || GeoParser::parsePointWithMaxDistance(embeddedObj, centroid.get(), &maxDistance)) { uassert(18522, "max distance must be non-negative", maxDistance >= 0.0); hasGeometry = true; isNearSphere = equals(e.fieldName(), "$nearSphere"); } } else if (equals(e.fieldName(), "$minDistance")) { uassert(16893, "$minDistance must be a number", e.isNumber()); minDistance = e.Number(); uassert(16894, "$minDistance must be non-negative", minDistance >= 0.0); } else if (equals(e.fieldName(), "$maxDistance")) { uassert(16895, "$maxDistance must be a number", e.isNumber()); maxDistance = e.Number(); uassert(16896, "$maxDistance must be non-negative", maxDistance >= 0.0); } else if (equals(e.fieldName(), "$uniqueDocs")) { warning() << "ignoring deprecated option $uniqueDocs"; } else { // In a query document, $near queries can have no non-geo sibling parameters. uasserted(34413, str::stream() << "invalid argument in geo near query: " << e.fieldName()); } } return hasGeometry; }
intrusive_ptr<DocumentSource> DocumentSourceCollStats::createFromBson( BSONElement specElem, const intrusive_ptr<ExpressionContext>& pExpCtx) { uassert(40166, str::stream() << "$collStats must take a nested object but found: " << specElem, specElem.type() == BSONType::Object); intrusive_ptr<DocumentSourceCollStats> collStats(new DocumentSourceCollStats(pExpCtx)); for (const auto& elem : specElem.embeddedObject()) { StringData fieldName = elem.fieldNameStringData(); if ("latencyStats" == fieldName) { uassert(40167, str::stream() << "latencyStats argument must be an object, but got " << elem << " of type " << typeName(elem.type()), elem.type() == BSONType::Object); if (!elem["histograms"].eoo()) { uassert(40305, str::stream() << "histograms option to latencyStats must be bool, got " << elem << "of type " << typeName(elem.type()), elem["histograms"].isBoolean()); } } else if ("storageStats" == fieldName) { uassert(40279, str::stream() << "storageStats argument must be an object, but got " << elem << " of type " << typeName(elem.type()), elem.type() == BSONType::Object); } else if ("count" == fieldName) { uassert(40480, str::stream() << "count argument must be an object, but got " << elem << " of type " << typeName(elem.type()), elem.type() == BSONType::Object); } else { uasserted(40168, str::stream() << "unrecognized option to $collStats: " << fieldName); } } collStats->_collStatsSpec = specElem.Obj().getOwned(); return collStats; }
Status ModifierObjectReplace::init(const BSONElement& modExpr, const Options& opts, bool* positional) { if (modExpr.type() != Object) { // Impossible, really since the caller check this already... return Status(ErrorCodes::BadValue, str::stream() << "Document replacement expects a complete document" " but the type supplied was " << modExpr.type()); } // Object replacements never have positional operator. if (positional) *positional = false; // 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(); return fixupTimestamps(_val); }
void DBConfig::unserialize(const BSONObj& from){ _name = from.getStringField("name"); _shardingEnabled = from.getBoolField("partitioned"); _primary = from.getStringField("primary"); _sharded.clear(); BSONObj sharded = from.getObjectField( "sharded" ); if ( ! sharded.isEmpty() ){ BSONObjIterator i(sharded); while ( i.more() ){ BSONElement e = i.next(); uassert( 10182 , "sharded things have to be objects" , e.type() == Object ); BSONObj c = e.embeddedObject(); uassert( 10183 , "key has to be an object" , c["key"].type() == Object ); _sharded[e.fieldName()] = CollectionInfo( c["key"].embeddedObject() , c["unique"].trueValue() ); } } }
boost::intrusive_ptr<DocumentSource> DocumentSourceInternalSplitPipeline::createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) { uassert(ErrorCodes::TypeMismatch, str::stream() << "$_internalSplitPipeline must take a nested object but found: " << elem, elem.type() == BSONType::Object); auto specObj = elem.embeddedObject(); HostTypeRequirement mergeType = HostTypeRequirement::kNone; for (auto&& elt : specObj) { if (elt.fieldNameStringData() == "mergeType"_sd) { uassert(ErrorCodes::BadValue, str::stream() << "'mergeType' must be a string value but found: " << elt.type(), elt.type() == BSONType::String); auto mergeTypeString = elt.valueStringData(); if ("localOnly"_sd == mergeTypeString) { mergeType = HostTypeRequirement::kLocalOnly; } else if ("anyShard"_sd == mergeTypeString) { mergeType = HostTypeRequirement::kAnyShard; } else if ("primaryShard"_sd == mergeTypeString) { mergeType = HostTypeRequirement::kPrimaryShard; } else if ("mongos"_sd == mergeTypeString) { mergeType = HostTypeRequirement::kMongoS; } else { uasserted(ErrorCodes::BadValue, str::stream() << "unrecognized field while parsing mergeType: '" << elt.fieldNameStringData() << "'"); } } else { uasserted(ErrorCodes::BadValue, str::stream() << "unrecognized field while parsing $_internalSplitPipeline: '" << elt.fieldNameStringData() << "'"); } } return new DocumentSourceInternalSplitPipeline(expCtx, mergeType); }
void BSONElementHasher::recursiveHash( Hasher* h , const BSONElement& e , bool includeFieldName ) { int canonicalType = e.canonicalType(); h->addData( &canonicalType , sizeof( canonicalType ) ); if ( includeFieldName ){ h->addData( e.fieldName() , e.fieldNameSize() ); } if ( !e.mayEncapsulate() ){ //if there are no embedded objects (subobjects or arrays), //compute the hash, squashing numeric types to 64-bit ints if ( e.isNumber() ){ long long int i = e.safeNumberLong(); //well-defined for troublesome doubles h->addData( &i , sizeof( i ) ); } else { h->addData( e.value() , e.valuesize() ); } } else { //else identify the subobject. //hash any preceding stuff (in the case of codeWscope) //then each sub-element //then finish with the EOO element. BSONObj b; if ( e.type() == CodeWScope ) { h->addData( e.codeWScopeCode() , e.codeWScopeCodeLen() ); b = e.codeWScopeObject(); } else { b = e.embeddedObject(); } BSONObjIterator i(b); while( i.moreWithEOO() ) { BSONElement el = i.next(); recursiveHash( h , el , true ); } } }
boost::optional<Document> DocumentSourceCommandShards::getNext() { pExpCtx->checkForInterrupt(); while(true) { if (!pBsonSource.get()) { /* if there aren't any more futures, we're done */ if (iterator == listEnd) return boost::none; /* grab the next command result */ BSONObj resultObj = iterator->result; uassert(16390, str::stream() << "sharded pipeline failed on shard " << iterator->shardTarget.getName() << ": " << resultObj.toString(), resultObj["ok"].trueValue()); /* grab the result array out of the shard server's response */ BSONElement resultArray = resultObj["result"]; massert(16391, str::stream() << "no result array? shard:" << iterator->shardTarget.getName() << ": " << resultObj.toString(), resultArray.type() == Array); // done with error checking, don't need the shard name anymore ++iterator; if (resultArray.embeddedObject().isEmpty()){ // this shard had no results, on to the next one continue; } pBsonSource = DocumentSourceBsonArray::create(&resultArray, pExpCtx); } if (boost::optional<Document> out = pBsonSource->getNext()) return out; // Source exhausted. Try next. pBsonSource.reset(); } }
Status LiteParsedQuery::init(const string& ns, int ntoskip, int ntoreturn, int queryOptions, const BSONObj& queryObj, const BSONObj& proj, bool fromQueryMessage) { _ns = ns; _ntoskip = ntoskip; _ntoreturn = ntoreturn; _options = queryOptions; _proj = proj.getOwned(); if (_ntoskip < 0) { return Status(ErrorCodes::BadValue, "bad skip value in query"); } if (_ntoreturn < 0) { // _ntoreturn greater than zero is simply a hint on how many objects to send back per // "cursor batch". A negative number indicates a hard limit. _wantMore = false; _ntoreturn = -_ntoreturn; } if (fromQueryMessage) { BSONElement queryField = queryObj["query"]; if (!queryField.isABSONObj()) { queryField = queryObj["$query"]; } if (queryField.isABSONObj()) { _filter = queryField.embeddedObject().getOwned(); Status status = initFullQuery(queryObj); if (!status.isOK()) { return status; } } else { // TODO: Does this ever happen? _filter = queryObj.getOwned(); } } else { // This is the debugging code path. _filter = queryObj.getOwned(); } _hasReadPref = queryObj.hasField("$readPreference"); return Status::OK(); }
static bool isLegacyCenterSphere(const BSONObj &obj) { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); if (!type.isABSONObj()) { return false; } bool isCenterSphere = mongoutils::str::equals(type.fieldName(), "$centerSphere"); if (!isCenterSphere) { return false; } BSONObjIterator objIt(type.embeddedObject()); BSONElement center = objIt.next(); if (!center.isABSONObj()) { return false; } if (!isLegacyPoint(center.Obj())) { return false; } // Check to make sure the points are valid lng/lat. BSONObjIterator coordIt(center.Obj()); BSONElement lng = coordIt.next(); BSONElement lat = coordIt.next(); if (!isValidLngLat(lng.Number(), lat.Number())) { return false; } if (!objIt.more()) { return false; } BSONElement radius = objIt.next(); if (!radius.isNumber()) { return false; } return true; }
bool GeoParser::parsePolygon(const BSONObj &obj, PolygonWithCRS *out) { if (isGeoJSONPolygon(obj)) { const vector<BSONElement>& coordinates = obj.getFieldDotted(GEOJSON_COORDINATES).Array(); if (!parseGeoJSONPolygonCoordinates(coordinates, obj, &out->polygon)) { return false; } out->crs = SPHERE; } else { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); BSONObjIterator coordIt(type.embeddedObject()); vector<Point> points; while (coordIt.more()) { Point p; if (!parseLegacyPoint(coordIt.next().Obj(), &p)) { return false; } points.push_back(p); } out->oldPolygon = Polygon(points); out->crs = FLAT; } return true; }
BSONElement BSONObj::getFieldDottedOrArray(const char *&name) const { const char *p = strchr(name, '.'); string left; if ( p ) { left = string(name, p-name); name = p + 1; } else { left = string(name); name = name + strlen(name); } BSONElement sub = getField(left.c_str()); if ( sub.eoo() ) return nullElement; else if ( sub.type() == Array || strlen( name ) == 0 ) return sub; else if ( sub.type() == Object ) return sub.embeddedObject().getFieldDottedOrArray( name ); else return nullElement; }
Status Command::parseCommandCursorOptions(const BSONObj& cmdObj, long long defaultBatchSize, long long* batchSize) { invariant(batchSize); *batchSize = defaultBatchSize; BSONElement cursorElem = cmdObj["cursor"]; if (cursorElem.eoo()) { return Status::OK(); } if (cursorElem.type() != mongo::Object) { return Status(ErrorCodes::TypeMismatch, "cursor field must be missing or an object"); } BSONObj cursor = cursorElem.embeddedObject(); BSONElement batchSizeElem = cursor["batchSize"]; const int expectedNumberOfCursorFields = batchSizeElem.eoo() ? 0 : 1; if (cursor.nFields() != expectedNumberOfCursorFields) { return Status(ErrorCodes::BadValue, "cursor object can't contain fields other than batchSize"); } if (batchSizeElem.eoo()) { return Status::OK(); } if (!batchSizeElem.isNumber()) { return Status(ErrorCodes::TypeMismatch, "cursor.batchSize must be a number"); } // This can change in the future, but for now all negatives are reserved. if (batchSizeElem.numberLong() < 0) { return Status(ErrorCodes::BadValue, "cursor.batchSize must not be negative"); } *batchSize = batchSizeElem.numberLong(); return Status::OK(); }
bool NearQuery::parseLegacyQuery(const BSONObj &obj) { bool hasGeometry = false; // First, try legacy near, e.g.: // t.find({ loc : { $nearSphere: [0,0], $minDistance: 1, $maxDistance: 3 }}) // t.find({ loc : { $nearSphere: [0,0] }}) // t.find({ loc : { $near : [0, 0, 1] } }); // t.find({ loc : { $near: { someGeoJSONPoint}}) // t.find({ loc : { $geoNear: { someGeoJSONPoint}}) BSONObjIterator it(obj); while (it.more()) { BSONElement e = it.next(); if (equals(e.fieldName(), "$near") || equals(e.fieldName(), "$geoNear") || equals(e.fieldName(), "$nearSphere")) { if (!e.isABSONObj()) { return false; } BSONObj embeddedObj = e.embeddedObject(); if ((GeoParser::isPoint(embeddedObj) && GeoParser::parsePoint(embeddedObj, ¢roid)) || GeoParser::parsePointWithMaxDistance(embeddedObj, ¢roid, &maxDistance)) { uassert(18522, "max distance must be non-negative", maxDistance >= 0.0); hasGeometry = true; isNearSphere = equals(e.fieldName(), "$nearSphere"); } } else if (equals(e.fieldName(), "$minDistance")) { uassert(16893, "$minDistance must be a number", e.isNumber()); minDistance = e.Number(); uassert(16894, "$minDistance must be non-negative", minDistance >= 0.0); } else if (equals(e.fieldName(), "$maxDistance")) { uassert(16895, "$maxDistance must be a number", e.isNumber()); maxDistance = e.Number(); uassert(16896, "$maxDistance must be non-negative", maxDistance >= 0.0); } else if (equals(e.fieldName(), "$uniqueDocs")) { warning() << "ignoring deprecated option $uniqueDocs"; } } return hasGeometry; }
void Chunk::unserialize(const BSONObj& from){ _ns = from.getStringField( "ns" ); _shard = from.getStringField( "shard" ); _lastmod = from.hasField( "lastmod" ) ? from["lastmod"]._numberLong() : 0; BSONElement e = from["minDotted"]; cout << from << endl; if (e.eoo()){ _min = from.getObjectField( "min" ).getOwned(); _max = from.getObjectField( "max" ).getOwned(); } else { // TODO delete this case after giving people a chance to migrate _min = e.embeddedObject().getOwned(); _max = from.getObjectField( "maxDotted" ).getOwned(); } uassert( 10170 , "Chunk needs a ns" , ! _ns.empty() ); uassert( 10171 , "Chunk needs a server" , ! _ns.empty() ); uassert( 10172 , "Chunk needs a min" , ! _min.isEmpty() ); uassert( 10173 , "Chunk needs a max" , ! _max.isEmpty() ); }
static bool _hasShardKey(const BSONObj& doc, const set<string>& patternFields, bool allowRegex) { // this is written s.t. if doc has lots of fields, if the shard key fields are early, // it is fast. so a bit more work to try to be semi-fast. for (set<string>::const_iterator it = patternFields.begin(); it != patternFields.end(); ++it) { BSONElement shardKeyField = doc.getFieldDotted(it->c_str()); if (shardKeyField.eoo() || shardKeyField.type() == Array || (!allowRegex && shardKeyField.type() == RegEx) || (shardKeyField.type() == Object && !shardKeyField.embeddedObject().okForStorage())) { // Don't allow anything for a shard key we can't store -- like $gt/$lt ops return false; } } return true; }
FieldParser::FieldState FieldParser::extract(BSONElement elem, const BSONField<BSONArray>& field, BSONArray* out, string* errMsg) { if (elem.eoo()) { if (field.hasDefault()) { *out = field.getDefault(); return FIELD_DEFAULT; } else { return FIELD_NONE; } } if (elem.type() == Array) { *out = BSONArray(elem.embeddedObject().getOwned()); return FIELD_SET; } _genFieldErrMsg(elem, field, "array", errMsg); return FIELD_INVALID; }
StatusWithMatchExpression JSONSchemaParser::_parseProperties(StringData path, BSONElement propertiesElt, TypeMatchExpression* typeExpr) { if (propertiesElt.type() != BSONType::Object) { return {Status(ErrorCodes::TypeMismatch, str::stream() << "$jsonSchema keyword '" << kSchemaPropertiesKeyword << "' must be an object")}; } auto propertiesObj = propertiesElt.embeddedObject(); auto andExpr = stdx::make_unique<AndMatchExpression>(); for (auto&& property : propertiesObj) { if (property.type() != BSONType::Object) { return {ErrorCodes::TypeMismatch, str::stream() << "Nested schema for $jsonSchema property '" << property.fieldNameStringData() << "' must be an object"}; } auto nestedSchemaMatch = _parse(property.fieldNameStringData(), property.embeddedObject()); if (!nestedSchemaMatch.isOK()) { return nestedSchemaMatch.getStatus(); } andExpr->add(nestedSchemaMatch.getValue().release()); } // If this is a top-level schema, then we have no path and there is no need for an // explicit object match node. if (path.empty()) { return {std::move(andExpr)}; } auto objectMatch = stdx::make_unique<InternalSchemaObjectMatchExpression>(); auto objectMatchStatus = objectMatch->init(std::move(andExpr), path); if (!objectMatchStatus.isOK()) { return objectMatchStatus; } return makeRestriction(BSONType::Object, std::move(objectMatch), typeExpr); }
bool GeoQuery::parseLegacyQuery(const BSONObj &obj) { // The only legacy syntax is {$within: {.....}} BSONObjIterator outerIt(obj); if (!outerIt.more()) { return false; } BSONElement withinElt = outerIt.next(); if (outerIt.more()) { return false; } if (!withinElt.isABSONObj()) { return false; } if (!equals(withinElt.fieldName(), "$within") && !equals(withinElt.fieldName(), "$geoWithin")) { return false; } BSONObj withinObj = withinElt.embeddedObject(); bool hasGeometry = false; BSONObjIterator withinIt(withinObj); while (withinIt.more()) { BSONElement elt = withinIt.next(); if (equals(elt.fieldName(), "$uniqueDocs")) { warning() << "deprecated $uniqueDocs option: " << obj.toString() << endl; // return false; } else if (elt.isABSONObj()) { hasGeometry = geoContainer.parseFrom(elt.wrap()); } else { warning() << "bad geo query: " << obj.toString() << endl; return false; } } predicate = GeoQuery::WITHIN; return hasGeometry; }
intrusive_ptr<DocumentSource> DocumentSourceMergeCursors::createFromBson( BSONElement elem, const intrusive_ptr<ExpressionContext>& pExpCtx) { massert(17026, string("Expected an Array, but got a ") + typeName(elem.type()), elem.type() == Array); std::vector<CursorDescriptor> cursorDescriptors; BSONObj array = elem.embeddedObject(); BSONForEach(cursor, array) { massert(17027, string("Expected an Object, but got a ") + typeName(cursor.type()), cursor.type() == Object); // The cursor descriptors for the merge cursors stage used to lack an "ns" field; "ns" was // understood to be the expression context namespace in that case. For mixed-version // compatibility, we accept both the old and new formats here. std::string cursorNs = cursor["ns"] ? cursor["ns"].String() : pExpCtx->ns.ns(); cursorDescriptors.emplace_back(ConnectionString(HostAndPort(cursor["host"].String())), std::move(cursorNs), cursor["id"].Long()); }
BSONElement extractElementAtPathOrArrayAlongPath(const BSONObj& obj, const char*& path) { const char* p = strchr(path, '.'); BSONElement sub; if (p) { sub = obj.getField(std::string(path, p - path)); path = p + 1; } else { sub = obj.getField(path); path = path + strlen(path); } if (sub.eoo()) return BSONElement(); else if (sub.type() == Array || path[0] == '\0') return sub; else if (sub.type() == Object) return extractElementAtPathOrArrayAlongPath(sub.embeddedObject(), path); else return BSONElement(); }
virtual IndexSuitability suitability( const FieldRangeSet& queryConstraints , const BSONObj& order ) const { BSONObj query = queryConstraints.originalQuery(); for (size_t i = 0; i < _fields.size(); ++i) { const IndexedField &field = _fields[i]; if (IndexedField::GEO != field.type) { continue; } BSONElement e = query.getFieldDotted(field.name); // Some locations are given to us as arrays. Sigh. if (Array == e.type()) { return HELPFUL; } if (Object != e.type()) { continue; } // getGtLtOp is horribly misnamed and really means get the operation. switch (e.embeddedObject().firstElement().getGtLtOp()) { case BSONObj::opNEAR: case BSONObj::opGEO_INTERSECTS: return OPTIMAL; default: return HELPFUL; } } return USELESS; }
/** * 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. */ 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); _addPrivilegesForSystemRole(dbname, roleElement.str(), outPrivileges); } return Status::OK(); }
DiskLoc ArtificialTreeBuilder<OnDiskFormat>::makeTree(const BSONObj& spec) { DiskLoc bucketLoc = _helper->btree._addBucket(_opCtx); BucketType* bucket = _helper->btree.getBucket(_opCtx, bucketLoc); BSONObjIterator i(spec); while (i.more()) { BSONElement e = i.next(); DiskLoc child; if (e.type() == Object) { child = makeTree(e.embeddedObject()); } if (e.fieldName() == string("_")) { bucket->nextChild = child; } else { KeyDataOwnedType key(BSON("" << expectedKey(e.fieldName()))); invariant(_helper->btree.pushBack(bucket, _helper->dummyDiskLoc, key, child)); } } _helper->btree.fixParentPtrs(_opCtx, bucket, bucketLoc); return bucketLoc; }
Status _initializeUserRolesFromV1RolesArray(User* user, const BSONElement& rolesElement, const StringData& dbname) { static const char privilegesTypeMismatchMessage[] = "Roles in V1 user documents must be enumerated in an array of strings."; if (dbname == AuthorizationManager::WILDCARD_RESOURCE_NAME) { return Status(ErrorCodes::BadValue, AuthorizationManager::WILDCARD_RESOURCE_NAME + " 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); user->addRole(RoleName(roleElement.String(), dbname)); } return Status::OK(); }
intrusive_ptr<DocumentSource> DocumentSourceSample::createFromBson( BSONElement specElem, const intrusive_ptr<ExpressionContext>& expCtx) { uassert(28745, "the $sample stage specification must be an object", specElem.type() == Object); intrusive_ptr<DocumentSourceSample> sample(new DocumentSourceSample(expCtx)); bool sizeSpecified = false; for (auto&& elem : specElem.embeddedObject()) { auto fieldName = elem.fieldNameStringData(); if (fieldName == "size") { uassert(28746, "size argument to $sample must be a number", elem.isNumber()); uassert(28747, "size argument to $sample must not be negative", elem.numberLong() >= 0); sample->_size = elem.numberLong(); sizeSpecified = true; } else { uasserted(28748, str::stream() << "unrecognized option to $sample: " << fieldName); } } uassert(28749, "$sample stage must specify a size", sizeSpecified); sample->_sortStage = DocumentSourceSort::create(expCtx, randSortSpec, sample->_size); return sample; }
// todo: can be a little faster if we don't use toString() here. bool BSONObj::valid() const { try{ BSONObjIterator it(*this); while( it.moreWithEOO() ){ // both throw exception on failure BSONElement e = it.next(true); e.validate(); if (e.eoo()){ if (it.moreWithEOO()) return false; return true; }else if (e.isABSONObj()){ if(!e.embeddedObject().valid()) return false; }else if (e.type() == CodeWScope){ if(!e.codeWScopeObject().valid()) return false; } } } catch (...) { } return false; }
Status _checkV2RolesArray(const BSONElement& rolesElement) { StringData fieldName = rolesElement.fieldNameStringData(); if (rolesElement.eoo()) { return _badValue(mongoutils::str::stream() << "User document needs '" << fieldName << "' field to be provided", 0); } if (rolesElement.type() != Array) { return _badValue(mongoutils::str::stream() << fieldName << " field must be an array", 0); } for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) { if ((*iter).type() != Object) { return _badValue(mongoutils::str::stream() << "Elements in '" << fieldName << "' array must objects.", 0); } BSONObj roleObj = (*iter).Obj(); BSONElement nameElement = roleObj[ROLE_NAME_FIELD_NAME]; BSONElement sourceElement = roleObj[ROLE_SOURCE_FIELD_NAME]; if (nameElement.type() != String || makeStringDataFromBSONElement(nameElement).empty()) { return _badValue(mongoutils::str::stream() << "Entries in '" << fieldName << "' array need 'name' field to be a non-empty string", 0); } if (sourceElement.type() != String || makeStringDataFromBSONElement(sourceElement).empty()) { return _badValue(mongoutils::str::stream() << "Entries in '" << fieldName << "' array need 'source' field to be a non-empty string", 0); } } return Status::OK(); }
FieldParser::FieldState FieldParser::extract(BSONObj doc, const BSONField<BSONObj>& field, BSONObj* out, string* errMsg) { BSONElement elem = doc[field.name()]; if (elem.eoo()) { if (field.hasDefault()) { *out = field.getDefault(); return FIELD_DEFAULT; } else { return FIELD_NONE; } } if (elem.type() == Object) { *out = elem.embeddedObject().getOwned(); return FIELD_SET; } _genFieldErrMsg(doc, field, "object", errMsg); return FIELD_INVALID; }