bool GeoParser::parseCap(const BSONObj& obj, CapWithCRS *out) { if (isLegacyCenter(obj)) { BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); BSONObjIterator objIt(type.embeddedObject()); BSONElement center = objIt.next(); if (!parseLegacyPoint(center.Obj(), &out->circle.center)) { return false; } BSONElement radius = objIt.next(); out->circle.radius = radius.number(); out->crs = FLAT; } else { verify(isLegacyCenterSphere(obj)); BSONObjIterator typeIt(obj); BSONElement type = typeIt.next(); BSONObjIterator objIt(type.embeddedObject()); BSONObj centerObj = objIt.next().Obj(); S2Point centerPoint; BSONObjIterator it(centerObj); BSONElement x = it.next(); BSONElement y = it.next(); centerPoint = coordToPoint(x.Number(), y.Number()); BSONElement radiusElt = objIt.next(); double radius = radiusElt.number(); out->cap = S2Cap::FromAxisAngle(centerPoint, S1Angle::Radians(radius)); out->circle.radius = radius; out->circle.center = Point(x.Number(), y.Number()); out->crs = SPHERE; } return true; }
bool GeoParser::parsePointWithMaxDistance(const BSONObj& obj, PointWithCRS* out, double* maxOut) { BSONObjIterator it(obj); if (!it.more()) { return false; } BSONElement lng = it.next(); if (!lng.isNumber()) { return false; } if (!it.more()) { return false; } BSONElement lat = it.next(); if (!lat.isNumber()) { return false; } if (!it.more()) { return false; } BSONElement dist = it.next(); if (!dist.isNumber()) { return false; } if (it.more()) { return false; } out->crs = FLAT; out->oldPoint.x = lng.number(); out->oldPoint.y = lat.number(); *maxOut = dist.number(); if (isValidLngLat(lng.Number(), lat.Number())) { out->flatUpgradedToSphere = true; out->point = coordToPoint(lng.Number(), lat.Number()); out->cell = S2Cell(out->point); } return true; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__RTNREELECT_INIT, "_rtnReelect::init" ) INT32 _rtnReelect::init ( INT32 flags, INT64 numToSkip, INT64 numToReturn, const CHAR *pMatcherBuff, const CHAR *pSelectBuff, const CHAR *pOrderByBuff, const CHAR *pHintBuff ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__RTNREELECT_INIT ) ; BSONObj obj ; try { obj = BSONObj( pMatcherBuff ) ; BSONElement e = obj.getField( FIELD_NAME_REELECTION_TIMEOUT ) ; if ( !e.eoo() ) { if ( !e.isNumber() ) { PD_LOG( PDERROR, "invalid reelection msg:%s", obj.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } _timeout = e.Number() ; } e = obj.getField( FIELD_NAME_REELECTION_LEVEL ) ; if ( !e.eoo() ) { if ( !e.isNumber() ) { PD_LOG( PDERROR, "invalid reelection msg:%s", obj.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } _level = ( CLS_REELECTION_LEVEL )((INT32)e.Number()) ; } } catch ( std::exception &e ) { PD_LOG( PDERROR, "unexpected error happened:%s", e.what() ) ; rc = SDB_SYS ; goto error ; } done: PD_TRACE_EXITRC( SDB__RTNREELECT_INIT, rc ) ; return rc ; error: goto done ; }
void ExpressionParams::parseTwoDParams(const BSONObj& infoObj, TwoDIndexingParams* out) { BSONObjIterator i(infoObj.getObjectField("key")); while (i.more()) { BSONElement e = i.next(); if (e.type() == String && IndexNames::GEO_2D == e.valuestr()) { uassert(16800, "can't have 2 geo fields", out->geo.size() == 0); uassert(16801, "2d has to be first in index", out->other.size() == 0); out->geo = e.fieldName(); } else { int order = 1; if (e.isNumber()) { order = static_cast<int>(e.Number()); } out->other.push_back(std::make_pair(e.fieldName(), order)); } } uassert(16802, "no geo field specified", out->geo.size()); GeoHashConverter::Parameters hashParams; Status paramStatus = GeoHashConverter::parseParameters(infoObj, &hashParams); uassertStatusOK(paramStatus); out->geoHashConverter.reset(new GeoHashConverter(hashParams)); }
bool parseLegacy(const BSONObj &obj, QueryGeometry *out, bool *isNear, bool *intersect, double *maxDistance) const { // Legacy intersect parsing: t.find({ loc : [0,0] }) if (out->parseFrom(obj)) { *isNear = true; return true; } bool ret = false; BSONObjIterator it(obj); while (it.more()) { BSONElement e = it.next(); if (!e.isABSONObj()) { return false; } BSONObj embeddedObj = e.embeddedObject(); // Legacy near parsing: t.find({ loc : { $near: [0,0], $maxDistance: 3 }}) // Legacy near parsing: t.find({ loc : { $near: [0,0] }}) if (mongoutils::str::equals(e.fieldName(), "$near")) { if (out->parseFrom(embeddedObj)) { uassert(16573, "near requires point, given " + embeddedObj.toString(), GeoParser::isPoint(embeddedObj)); *isNear = true; ret = true; } } else if (mongoutils::str::equals(e.fieldName(), "$maxDistance")) { *maxDistance = e.Number(); } } return ret; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__RTNFORCESTEPUP_INIT, "_rtnForceStepUp::init" ) INT32 _rtnForceStepUp::init( INT32 flags, INT64 numToSkip, INT64 numToReturn, const CHAR *pMatcherBuff, const CHAR *pSelectBuff, const CHAR *pOrderByBuff, const CHAR *pHintBuff ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__RTNFORCESTEPUP_INIT ) ; BSONObj options ; try { options = BSONObj( pMatcherBuff ).copy() ; BSONElement e = options.getField( FIELD_NAME_FORCE_STEP_UP_TIME ) ; if ( e.isNumber() ) { _seconds = e.Number() ; } } catch ( std::exception &e ) { PD_LOG( PDERROR, "unexpected error happened:%s", e.what() ) ; rc = SDB_SYS ; goto error ; } done: PD_TRACE_EXITRC( SDB__RTNFORCESTEPUP_INIT, rc ) ; return rc ; error: goto done ; }
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; }
bool GeoParser::parsePoint(const BSONObj &obj, PointWithCRS *out) { if (isLegacyPoint(obj, true)) { BSONObjIterator it(obj); BSONElement x = it.next(); BSONElement y = it.next(); out->oldPoint.x = x.Number(); out->oldPoint.y = y.Number(); out->crs = FLAT; } else if (isGeoJSONPoint(obj)) { const vector<BSONElement>& coords = obj.getFieldDotted(GEOJSON_COORDINATES).Array(); out->oldPoint.x = coords[0].Number(); out->oldPoint.y = coords[1].Number(); out->crs = FLAT; if (!ShapeProjection::supportsProject(*out, SPHERE)) return false; ShapeProjection::projectInto(out, SPHERE); } return true; }
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 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; }
bool GeoParser::parsePoint(const BSONObj &obj, PointWithCRS *out) { if (isGeoJSONPoint(obj)) { const vector<BSONElement>& coords = obj.getFieldDotted(GEOJSON_COORDINATES).Array(); out->point = coordToPoint(coords[0].Number(), coords[1].Number()); out->cell = S2Cell(out->point); out->oldPoint.x = coords[0].Number(); out->oldPoint.y = coords[1].Number(); out->crs = SPHERE; } else if (isLegacyPoint(obj)) { BSONObjIterator it(obj); BSONElement x = it.next(); BSONElement y = it.next(); out->point = coordToPoint(x.Number(), y.Number()); out->cell = S2Cell(out->point); out->oldPoint.x = x.Number(); out->oldPoint.y = y.Number(); out->crs = FLAT; } return true; }
bool BatchedCommandRequest::isVerboseWC() const { if (!isWriteConcernSet()) { return true; } BSONObj writeConcern = getWriteConcern(); BSONElement wElem = writeConcern["w"]; if (!wElem.isNumber() || wElem.Number() != 0) { return true; } return false; }
/* **************************************************************************** * * addCompoundNode - * */ static void addCompoundNode(orion::CompoundValueNode* cvP, const BSONElement& e) { if ((e.type() != String) && (e.type() != Bool) && (e.type() != NumberDouble) && (e.type() != jstNULL) && (e.type() != Object) && (e.type() != Array)) { LM_E(("Runtime Error (unknown BSON type: %d)", e.type())); return; } orion::CompoundValueNode* child = new orion::CompoundValueNode(orion::ValueTypeObject); child->name = dbDotDecode(e.fieldName()); switch (e.type()) { case String: child->valueType = orion::ValueTypeString; child->stringValue = e.String(); break; case Bool: child->valueType = orion::ValueTypeBoolean; child->boolValue = e.Bool(); break; case NumberDouble: child->valueType = orion::ValueTypeNumber; child->numberValue = e.Number(); break; case jstNULL: child->valueType = orion::ValueTypeNone; break; case Object: compoundObjectResponse(child, e); break; case Array: compoundVectorResponse(child, e); break; default: // // We need the default clause to avoid 'enumeration value X not handled in switch' errors // due to -Werror=switch at compilation time // break; } cvP->add(child); }
bool parseQuery(const BSONObj &obj, QueryGeometry *out, bool *isNear, bool *intersect, double *maxDistance) const { // pointA = { "type" : "Point", "coordinates": [ 40, 5 ] } // t.find({ "geo" : { "$intersect" : { "$geometry" : pointA} } }) // t.find({ "geo" : { "$near" : { "$geometry" : pointA, $maxDistance : 20 }}}) // where field.name is "geo" BSONElement e = obj.firstElement(); if (!e.isABSONObj()) { return false; } BSONObj::MatchType matchType = static_cast<BSONObj::MatchType>(e.getGtLtOp()); if (BSONObj::opGEO_INTERSECTS == matchType) { *intersect = true; } else if (BSONObj::opNEAR == matchType) { *isNear = true; } else { return false; } bool ret = false; BSONObjIterator argIt(e.embeddedObject()); while (argIt.more()) { BSONElement e = argIt.next(); if (mongoutils::str::equals(e.fieldName(), "$geometry")) { if (e.isABSONObj()) { BSONObj embeddedObj = e.embeddedObject(); if (out->parseFrom(embeddedObj)) { uassert(16570, "near requires point, given " + embeddedObj.toString(), !(*isNear) || GeoParser::isPoint(embeddedObj)); ret = true; } } } else if (mongoutils::str::equals(e.fieldName(), "$maxDistance")) { if (e.isNumber()) { *maxDistance = e.Number(); } } } return ret; }
TwoDAccessMethod::TwoDAccessMethod(BtreeInMemoryState* btreeState) : BtreeBasedAccessMethod(btreeState) { const IndexDescriptor* descriptor = btreeState->descriptor(); BSONObjIterator i(descriptor->keyPattern()); while (i.more()) { BSONElement e = i.next(); if (e.type() == String && IndexNames::GEO_2D == e.valuestr()) { uassert(16800, "can't have 2 geo fields", _params.geo.size() == 0); uassert(16801, "2d has to be first in index", _params.other.size() == 0); _params.geo = e.fieldName(); } else { int order = 1; if (e.isNumber()) { order = static_cast<int>(e.Number()); } _params.other.push_back(make_pair(e.fieldName(), order)); } } uassert(16802, "no geo field specified", _params.geo.size()); double bits = configValueWithDefault(descriptor, "bits", 26); // for lat/long, ~ 1ft uassert(16803, "bits in geo index must be between 1 and 32", bits > 0 && bits <= 32); GeoHashConverter::Parameters params; params.bits = static_cast<unsigned>(bits); params.max = configValueWithDefault(descriptor, "max", 180.0); params.min = configValueWithDefault(descriptor, "min", -180.0); double numBuckets = (1024 * 1024 * 1024 * 4.0); params.scaling = numBuckets / (params.max - params.min); _params.geoHashConverter.reset(new GeoHashConverter(params)); BSONObjBuilder b; b.appendNull(""); _nullObj = b.obj(); _nullElt = _nullObj.firstElement(); }
static void bson2bamboo(const dclass::DistributedType *type, const BSONElement &element, Datagram &dg) { switch(type->get_type()) { case dclass::Type::T_INT8: { dg.add_int8(element.Int()); } break; case dclass::Type::T_INT16: { dg.add_int16(element.Int()); } break; case dclass::Type::T_INT32: { dg.add_int32(element.Int()); } break; case dclass::Type::T_INT64: { dg.add_int64(element.Int()); } break; case dclass::Type::T_UINT8: { dg.add_uint8(element.Int()); } break; case dclass::Type::T_UINT16: { dg.add_uint16(element.Int()); } break; case dclass::Type::T_UINT32: { dg.add_uint32(element.Int()); } break; case dclass::Type::T_UINT64: { dg.add_uint64(element.Int()); } break; case dclass::Type::T_CHAR: { string str = element.String(); if(str.size() != 1) { throw mongo::DBException("Expected single-length string for char field", 0); } dg.add_uint8(str[0]); } break; case dclass::Type::T_FLOAT32: { dg.add_float32(element.Number()); } break; case dclass::Type::T_FLOAT64: { dg.add_float64(element.Number()); } break; case dclass::Type::T_STRING: { dg.add_data(element.String()); } break; case dclass::Type::T_VARSTRING: { dg.add_string(element.String()); } break; case dclass::Type::T_BLOB: { int len; const uint8_t *rawdata = (const uint8_t *)element.binData(len); dg.add_data(rawdata, len); } break; case dclass::Type::T_VARBLOB: { int len; const uint8_t *rawdata = (const uint8_t *)element.binData(len); dg.add_blob(rawdata, len); } break; case dclass::Type::T_ARRAY: { const dclass::ArrayType *array = type->as_array(); std::vector<BSONElement> data = element.Array(); for(auto it = data.begin(); it != data.end(); ++it) { bson2bamboo(array->get_element_type(), *it, dg); } } break; case dclass::Type::T_VARARRAY: { const dclass::ArrayType *array = type->as_array(); std::vector<BSONElement> data = element.Array(); DatagramPtr newdg = Datagram::create(); for(auto it = data.begin(); it != data.end(); ++it) { bson2bamboo(array->get_element_type(), *it, *newdg); } dg.add_blob(newdg->get_data(), newdg->size()); } break; case dclass::Type::T_STRUCT: { const dclass::Struct *s = type->as_struct(); size_t fields = s->get_num_fields(); for(unsigned int i = 0; i < fields; ++i) { const dclass::Field *field = s->get_field(i); bson2bamboo(field->get_type(), element[field->get_name()], dg); } } break; case dclass::Type::T_METHOD: { const dclass::Method *m = type->as_method(); size_t parameters = m->get_num_parameters(); for(unsigned int i = 0; i < parameters; ++i) { const dclass::Parameter *parameter = m->get_parameter(i); string name = parameter->get_name(); if(name.empty() || element[name].eoo()) { stringstream n; n << "_" << i; name = n.str(); } bson2bamboo(parameter->get_type(), element[name], dg); } } break; case dclass::Type::T_INVALID: default: assert(false); break; } }
Status GeoNearExpression::parseNewQuery(const BSONObj &obj) { bool hasGeometry = false; BSONObjIterator objIt(obj); if (!objIt.more()) { return Status(ErrorCodes::BadValue, "empty geo near query object"); } BSONElement e = objIt.next(); // Just one arg. to $geoNear. if (objIt.more()) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "geo near accepts just one argument when querying for a GeoJSON " << "point. Extra field found: " << objIt.next()); } // Parse "new" near: // t.find({"geo" : {"$near" : {"$geometry": pointA, $minDistance: 1, $maxDistance: 3}}}) // t.find({"geo" : {"$geoNear" : {"$geometry": pointA, $minDistance: 1, $maxDistance: 3}}}) if (!e.isABSONObj()) { return Status(ErrorCodes::BadValue, "geo near query argument is not an object"); } BSONObj::MatchType matchType = static_cast<BSONObj::MatchType>(e.getGtLtOp()); if (BSONObj::opNEAR != matchType) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "invalid geo near query operator: " << e.fieldName()); } // Iterate over the argument. BSONObjIterator it(e.embeddedObject()); while (it.more()) { BSONElement e = it.next(); if (equals(e.fieldName(), "$geometry")) { if (e.isABSONObj()) { BSONObj embeddedObj = e.embeddedObject(); Status status = GeoParser::parseQueryPoint(e, centroid.get()); if (!status.isOK()) { return Status(ErrorCodes::BadValue, str::stream() << "invalid point in geo near query $geometry argument: " << embeddedObj << " " << status.reason()); } uassert(16681, "$near requires geojson point, given " + embeddedObj.toString(), (SPHERE == centroid->crs)); hasGeometry = true; } } else if (equals(e.fieldName(), "$minDistance")) { uassert(16897, "$minDistance must be a number", e.isNumber()); minDistance = e.Number(); uassert(16898, "$minDistance must be non-negative", minDistance >= 0.0); } else if (equals(e.fieldName(), "$maxDistance")) { uassert(16899, "$maxDistance must be a number", e.isNumber()); maxDistance = e.Number(); uassert(16900, "$maxDistance must be non-negative", maxDistance >= 0.0); } } if (!hasGeometry) { return Status(ErrorCodes::BadValue, "$geometry is required for geo near query"); } return Status::OK(); }