Esempio n. 1
0
 // find all oplog entries for a given OID in the oplog.refs collection and apply them
 // TODO this should be a range query on oplog.refs where _id.oid == oid and applyOps to
 // each entry found.  The locking of the query interleaved with the locking in the applyOps
 // did not work, so it a sequence of point queries.  
 // TODO verify that the query plan is a indexed lookup.
 // TODO verify that the query plan does not fetch too many docs and then only process one of them.
 void applyRefOp(BSONObj entry) {
     OID oid = entry["ref"].OID();
     LOG(3) << "apply ref " << entry << " oid " << oid << endl;
     long long seq = 0; // note that 0 is smaller than any of the seq numbers
     while (1) {
         BSONObj entry;
         {
             LOCK_REASON(lockReason, "repl: finding oplog.refs entry to apply");
             Client::ReadContext ctx(rsOplogRefs, lockReason);
             // TODO: Should this be using rsOplogRefsDetails, verifying non-null?
             Collection *cl = getCollection(rsOplogRefs);
             if (cl == NULL || !cl->findOne(BSON("_id" << BSON("$gt" << BSON("oid" << oid << "seq" << seq))), entry, true)) {
                 break;
             }
         }
         BSONElement e = entry.getFieldDotted("_id.seq");
         seq = e.Long();
         BSONElement eOID = entry.getFieldDotted("_id.oid");
         if (oid != eOID.OID()) {
             break;
         }
         LOG(3) << "apply " << entry << " seq=" << seq << endl;
         applyOps(entry["ops"].Array());
     }
 }
Esempio n. 2
0
 double StatUtil::diff( const string& name , const BSONObj& a , const BSONObj& b ) {
     BSONElement x = a.getFieldDotted( name.c_str() );
     BSONElement y = b.getFieldDotted( name.c_str() );
     if ( ! x.isNumber() || ! y.isNumber() )
         return -1;
     return ( y.number() - x.number() ) / _seconds;
 }
Esempio n. 3
0
    bool GeoParser::isGeoJSONPolygon(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_POLYGON != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        // Must be at least one element, the outer shell
        if (coordinates.empty()) { return false; }
        // Verify that the shell is a bunch'a coordinates.
        for (size_t i = 0; i < coordinates.size(); ++i) {
            if (Array != coordinates[i].type()) { return false; }
            const vector<BSONElement>& thisLoop = coordinates[i].Array();
            // A triangle is the simplest 2d shape, and we repeat a vertex, so, 4.
            if (thisLoop.size() < 4) { return false; }
            if (!isArrayOfCoordinates(thisLoop)) { return false; }
            if (!isLoopClosed(thisLoop)) { return false; }
        }
        return true;
    }
Esempio n. 4
0
 double StatUtil::percent( const char * outof , const char * val , const BSONObj& a , const BSONObj& b ) {
     double x = ( b.getFieldDotted( val ).number() - a.getFieldDotted( val ).number() );
     double y = ( b.getFieldDotted( outof ).number() - a.getFieldDotted( outof ).number() );
     if ( y == 0 )
         return 0;
     double p = x / y;
     p = (double)((int)(p * 1000)) / 10;
     return p;
 }
Esempio n. 5
0
    bool GeoParser::isLine(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_LINESTRING != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        return isValidLineString(coordElt.Array());
    }
Esempio n. 6
0
    static bool isGeoJSONPolygon(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_POLYGON != type.String()) { return false; }

        if (!GeoParser::crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        return isGeoJSONPolygonCoordinates(coordElt.Array());
    }
Esempio n. 7
0
    bool GeoParser::parsePolygon(const BSONObj &obj, PolygonWithCRS *out) {
        if (isGeoJSONPolygon(obj)) {
            const vector<BSONElement>& coordinates = obj.getFieldDotted(GEOJSON_COORDINATES).Array();

            if (!parseGeoJSONCRS(obj, &out->crs))
                return false;

            if (out->crs == SPHERE) {
                out->s2Polygon.reset(new S2Polygon());
                if (!parseGeoJSONPolygonCoordinates(coordinates, obj, out->s2Polygon.get())) {
                    return false;
                }
            }
            else if (out->crs == STRICT_SPHERE) {
                out->bigPolygon.reset(new BigSimplePolygon());
                if (!parseBigSimplePolygonCoordinates(coordinates, obj, out->bigPolygon.get())) {
                    return false;
                }
            }
        } 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.init(points);
            out->crs = FLAT;
        }
        return true;
    }
Esempio n. 8
0
 ShardStatus::ShardStatus( const Shard& shard , const BSONObj& obj , const BSONObj& dblistobj )
     : _shard( shard ), _isDraining(shard.isDraining()) {
     _dataSize = dblistobj.getFieldDotted("totalUncompressedSize").numberLong();
     _hasOpsQueued = obj["writeBacksQueued"].Bool();
     _writeLock = 0; // TODO
     _mongoVersion = obj["version"].String();
 }
Esempio n. 9
0
/* well ordered compare */
int BSONObj::woSortOrder(const BSONObj& other, const BSONObj& sortKey , bool useDotted ) const {
    if ( isEmpty() )
        return other.isEmpty() ? 0 : -1;
    if ( other.isEmpty() )
        return 1;

    uassert( 10060 ,  "woSortOrder needs a non-empty sortKey" , ! sortKey.isEmpty() );

    BSONObjIterator i(sortKey);
    while ( 1 ) {
        BSONElement f = i.next();
        if ( f.eoo() )
            return 0;

        BSONElement l = useDotted ? getFieldDotted( f.fieldName() ) : getField( f.fieldName() );
        if ( l.eoo() )
            l = staticNull.firstElement();
        BSONElement r = useDotted ? other.getFieldDotted( f.fieldName() ) : other.getField( f.fieldName() );
        if ( r.eoo() )
            r = staticNull.firstElement();

        int x = l.woCompare( r, false );
        if ( f.number() < 0 )
            x = -x;
        if ( x != 0 )
            return x;
    }
    return -1;
}
Esempio n. 10
0
Status GeoParser::parseMultiPolygon(const BSONObj& obj,
                                    bool skipValidation,
                                    MultiPolygonWithCRS* out) {
    Status status = Status::OK();
    status = parseGeoJSONCRS(obj, &out->crs);
    if (!status.isOK())
        return status;

    BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
    if (Array != coordElt.type())
        return BAD_VALUE("MultiPolygon coordinates must be an array");

    out->polygons.clear();
    vector<S2Polygon*>& polygons = out->polygons.mutableVector();

    BSONObjIterator it(coordElt.Obj());
    // Iterate array
    while (it.more()) {
        polygons.push_back(new S2Polygon());
        status = parseGeoJSONPolygonCoordinates(it.next(), skipValidation, polygons.back());
        if (!status.isOK())
            return status;
    }
    if (0 == polygons.size())
        return BAD_VALUE("MultiPolygon coordinates must have at least 1 element");

    return Status::OK();
}
Esempio n. 11
0
Status WiredTigerKVEngine::createSortedDataInterface(OperationContext* opCtx,
                                                     StringData ident,
                                                     const IndexDescriptor* desc) {
    _checkIdentPath(ident);

    std::string collIndexOptions;
    const Collection* collection = desc->getCollection();

    // Treat 'collIndexOptions' as an empty string when the collection member of 'desc' is NULL in
    // order to allow for unit testing WiredTigerKVEngine::createSortedDataInterface().
    if (collection) {
        const CollectionCatalogEntry* cce = collection->getCatalogEntry();
        const CollectionOptions collOptions = cce->getCollectionOptions(opCtx);

        if (!collOptions.indexOptionDefaults["storageEngine"].eoo()) {
            BSONObj storageEngineOptions = collOptions.indexOptionDefaults["storageEngine"].Obj();
            collIndexOptions =
                storageEngineOptions.getFieldDotted("wiredTiger.configString").valuestrsafe();
        }
    }

    StatusWith<std::string> result =
        WiredTigerIndex::generateCreateString(_indexOptions, collIndexOptions, *desc);
    if (!result.isOK()) {
        return result.getStatus();
    }

    std::string config = result.getValue();

    LOG(2) << "WiredTigerKVEngine::createSortedDataInterface ident: " << ident
           << " config: " << config;
    return wtRCToStatus(WiredTigerIndex::Create(opCtx, _uri(ident), config));
}
Esempio n. 12
0
        void getKeys( const BSONObj &obj, BSONObjSet &keys ) const {

            BSONElement loc = obj.getFieldDotted( _geo );
            if ( loc.eoo() )
                return;

            uassert( 13323 , "latlng not an array" , loc.isABSONObj() );
            string root;
            {
                BSONObjIterator i( loc.Obj() );
                BSONElement x = i.next();
                BSONElement y = i.next();
                root = makeString( hash(x) , hash(y) );
            }


            verify( _other.size() == 1 );

            BSONElementSet all;
            obj.getFieldsDotted( _other[0] , all );

            if ( all.size() == 0 ) {
                _add( obj , root , BSONElement() , keys );
            }
            else {
                for ( BSONElementSet::iterator i=all.begin(); i!=all.end(); ++i ) {
                    _add( obj , root , *i , keys );
                }
            }

        }
Esempio n. 13
0
Status FTSSpec::getIndexPrefix( const BSONObj& query, BSONObj* out ) const {
    if ( numExtraBefore() == 0 ) {
        *out = BSONObj();
        return Status::OK();
    }

    BSONObjBuilder b;
    for ( unsigned i = 0; i < numExtraBefore(); i++ ) {
        BSONElement e = query.getFieldDotted(extraBefore(i));
        if ( e.eoo() )
            return Status( ErrorCodes::BadValue,
                           str::stream()
                           << "need have an equality filter on: "
                           << extraBefore(i) );

        if ( e.isABSONObj() && e.Obj().firstElement().getGtLtOp( -1 ) != -1 )
            return Status( ErrorCodes::BadValue,
                           str::stream()
                           << "need have an equality filter on: "
                           << extraBefore(i) );

        b.append( e );
    }
    *out = b.obj();
    return Status::OK();
}
Esempio n. 14
0
    void GeoParser::parseGeoJSONPolygon(const BSONObj& obj, S2Polygon* out) {
        const vector<BSONElement>& coordinates =
            obj.getFieldDotted(GEOJSON_COORDINATES).Array();

        const vector<BSONElement>& exteriorRing = coordinates[0].Array();
        vector<S2Point> exteriorVertices;
        parsePoints(exteriorRing, &exteriorVertices);

        S2PolygonBuilderOptions polyOptions;
        polyOptions.set_validate(true);
        S2PolygonBuilder polyBuilder(polyOptions);
        S2Loop exteriorLoop(exteriorVertices);
        if (exteriorLoop.is_hole()) {
            exteriorLoop.Invert();
        }
        polyBuilder.AddLoop(&exteriorLoop);

        // Subsequent arrays of coordinates are interior rings/holes.
        for (size_t i = 1; i < coordinates.size(); ++i) {
            vector<S2Point> holePoints;
            parsePoints(coordinates[i].Array(), &holePoints);
            // Interior rings are clockwise.
            S2Loop holeLoop(holePoints);
            if (!holeLoop.is_hole()) {
                holeLoop.Invert();
            }
            polyBuilder.AddLoop(&holeLoop);
        }

        polyBuilder.AssemblePolygon(out, NULL);
    }
Esempio n. 15
0
    Status GeoParser::parseMultiLine(const BSONObj &obj, MultiLineWithCRS *out) {
        Status status = Status::OK();
        status = parseGeoJSONCRS(obj, &out->crs);
        if (!status.isOK()) return status;

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (Array != coordElt.type())
            return BAD_VALUE("MultiLineString coordinates must be an array");

        out->lines.clear();
        vector<S2Polyline*>& lines = out->lines.mutableVector();

        BSONObjIterator it(coordElt.Obj());

        // Iterate array
        while (it.more()) {
            lines.push_back(new S2Polyline());
            status = parseGeoJSONLineCoordinates(it.next(), lines.back());
            if (!status.isOK()) return status;
        }
        if (0 == lines.size())
            return BAD_VALUE("MultiLineString coordinates must have at least 1 element");

        return Status::OK();
    }
Esempio n. 16
0
    static void handleCursorCommand(CursorId id, BSONObj& cmdObj, BSONObjBuilder& result) {
        BSONElement batchSizeElem = cmdObj.getFieldDotted("cursor.batchSize");
        const long long batchSize = batchSizeElem.isNumber()
                                    ? batchSizeElem.numberLong()
                                    : 101; // same as query

        ClientCursorPin pin(id);
        ClientCursor* cursor = pin.c();

        massert(16958, "Cursor shouldn't have been deleted",
                cursor);

        verify(cursor->isAggCursor);
        PipelineRunner* runner = dynamic_cast<PipelineRunner*>(cursor->getRunner());
        verify(runner);
        try {
            const string cursorNs = cursor->ns(); // we need this after cursor may have been deleted

            // can't use result BSONObjBuilder directly since it won't handle exceptions correctly.
            BSONArrayBuilder resultsArray;
            const int byteLimit = MaxBytesToReturnToClientAtOnce;
            BSONObj next;
            for (int objCount = 0; objCount < batchSize; objCount++) {
                // The initial getNext() on a PipelineRunner may be very expensive so we don't do it
                // when batchSize is 0 since that indicates a desire for a fast return.
                if (runner->getNext(&next, NULL) != Runner::RUNNER_ADVANCED) {
                    pin.deleteUnderlying();
                    id = 0;
                    cursor = NULL; // make it an obvious error to use cursor after this point
                    break;
                }

                if (resultsArray.len() + next.objsize() > byteLimit) {
                    // too big. next will be the first doc in the second batch
                    runner->pushBack(next);
                    break;
                }

                resultsArray.append(next);
            }

            if (cursor) {
                // If a time limit was set on the pipeline, remaining time is "rolled over" to the
                // cursor (for use by future getmore ops).
                cursor->setLeftoverMaxTimeMicros( cc().curop()->getRemainingMaxTimeMicros() );
            }

            BSONObjBuilder cursorObj(result.subobjStart("cursor"));
            cursorObj.append("id", id);
            cursorObj.append("ns", cursorNs);
            cursorObj.append("firstBatch", resultsArray.arr());
            cursorObj.done();
        }
        catch (...) {
            // Clean up cursor on way out of scope.
            pin.deleteUnderlying();
            throw;
        }
    }
Esempio n. 17
0
    bool GeoParser::isGeoJSONLineString(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_LINESTRING != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinateArray = coordElt.Array();
        if (coordinateArray.size() < 2) { return false; }
        return isArrayOfCoordinates(coordinateArray);
    }
Esempio n. 18
0
    bool GeoParser::isMultiPoint(const BSONObj &obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_MULTI_POINT != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (0 == coordinates.size()) { return false; }
        return isArrayOfCoordinates(coordinates);
    }
Esempio n. 19
0
//  { "type": "GeometryCollection",
//    "geometries": [
//      { "type": "Point",
//        "coordinates": [100.0, 0.0]
//      },
//      { "type": "LineString",
//        "coordinates": [ [101.0, 0.0], [102.0, 1.0] ]
//      }
//    ]
//  }
Status GeoParser::parseGeometryCollection(const BSONObj& obj,
                                          bool skipValidation,
                                          GeometryCollection* out) {
    BSONElement coordElt = obj.getFieldDotted(GEOJSON_GEOMETRIES);
    if (Array != coordElt.type())
        return BAD_VALUE("GeometryCollection geometries must be an array");

    const vector<BSONElement>& geometries = coordElt.Array();
    if (0 == geometries.size())
        return BAD_VALUE("GeometryCollection geometries must have at least 1 element");

    for (size_t i = 0; i < geometries.size(); ++i) {
        if (Object != geometries[i].type())
            return BAD_VALUE("Element " << i << " of \"geometries\" is not an object");

        const BSONObj& geoObj = geometries[i].Obj();
        GeoJSONType type = parseGeoJSONType(geoObj);

        if (GEOJSON_UNKNOWN == type)
            return BAD_VALUE("Unknown GeoJSON type: " << geometries[i].toString(false));

        if (GEOJSON_GEOMETRY_COLLECTION == type)
            return BAD_VALUE(
                "GeometryCollections cannot be nested: " << geometries[i].toString(false));

        Status status = Status::OK();
        if (GEOJSON_POINT == type) {
            out->points.resize(out->points.size() + 1);
            status = parseGeoJSONPoint(geoObj, &out->points.back());
        } else if (GEOJSON_LINESTRING == type) {
            out->lines.mutableVector().push_back(new LineWithCRS());
            status = parseGeoJSONLine(geoObj, skipValidation, out->lines.vector().back());
        } else if (GEOJSON_POLYGON == type) {
            out->polygons.mutableVector().push_back(new PolygonWithCRS());
            status = parseGeoJSONPolygon(geoObj, skipValidation, out->polygons.vector().back());
        } else if (GEOJSON_MULTI_POINT == type) {
            out->multiPoints.mutableVector().push_back(new MultiPointWithCRS());
            status = parseMultiPoint(geoObj, out->multiPoints.mutableVector().back());
        } else if (GEOJSON_MULTI_LINESTRING == type) {
            out->multiLines.mutableVector().push_back(new MultiLineWithCRS());
            status = parseMultiLine(geoObj, skipValidation, out->multiLines.mutableVector().back());
        } else if (GEOJSON_MULTI_POLYGON == type) {
            out->multiPolygons.mutableVector().push_back(new MultiPolygonWithCRS());
            status = parseMultiPolygon(
                geoObj, skipValidation, out->multiPolygons.mutableVector().back());
        } else {
            // Should not reach here.
            invariant(false);
        }

        // Check parsing result.
        if (!status.isOK())
            return status;
    }

    return Status::OK();
}
Esempio n. 20
0
        // Entry point for a search.
        virtual shared_ptr<Cursor> newCursor(const BSONObj& query, const BSONObj& order,
                                             int numWanted) const {
            vector<QueryGeometry> regions;
            double maxDistance = DBL_MAX;
            bool isNear = false;
            bool isIntersect = false;

            // Go through the fields that we index, and for each geo one, make a QueryGeometry
            // object for the S2Cursor class to do intersection testing/cover generating with.
            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);
                if (e.eoo()) { continue; }
                if (!e.isABSONObj()) { continue; }
                BSONObj obj = e.Obj();

                QueryGeometry geoQueryField(field.name);
                if (parseLegacy(obj, &geoQueryField, &isNear, &isIntersect, &maxDistance)) {
                    regions.push_back(geoQueryField);
                } else if (parseQuery(obj, &geoQueryField, &isNear, &isIntersect, &maxDistance)) {
                    regions.push_back(geoQueryField);
                } else {
                    uasserted(16535, "can't parse query for *2d geo search: " + obj.toString());
                }
            }

            if (isNear && isIntersect ) {
                uasserted(16474, "Can't do both near and intersect, query: " +  query.toString());
            }

            // I copied this from 2d.cpp.  Guard against perversion.
            if (numWanted < 0) numWanted *= -1;
            if (0 == numWanted) numWanted = INT_MAX;

            BSONObjBuilder geoFieldsToNuke;
            for (size_t i = 0; i < _fields.size(); ++i) {
                const IndexedField &field = _fields[i];
                if (IndexedField::GEO != field.type) { continue; }
                geoFieldsToNuke.append(field.name, "");
            }
            // false means we want to filter OUT geoFieldsToNuke, not filter to include only that.
            BSONObj filteredQuery = query.filterFieldsUndotted(geoFieldsToNuke.obj(), false);

            if (isNear) {
                S2NearCursor *cursor = new S2NearCursor(keyPattern(), getDetails(), filteredQuery, regions,
                                                        _params, numWanted, maxDistance);
                return shared_ptr<Cursor>(cursor);
            } else {
                // Default to intersect.
                S2Cursor *cursor = new S2Cursor(keyPattern(), getDetails(), filteredQuery, regions, _params,
                                                numWanted);
                return shared_ptr<Cursor>(cursor);
            }
        }
Esempio n. 21
0
    //// What we publicly export
    bool GeoParser::isGeoJSONPoint(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_POINT != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (coordinates.size() != 2) { return false; }
        if (!coordinates[0].isNumber() || !coordinates[1].isNumber()) { return false; }
        double lat = coordinates[1].Number();
        return lat >= -90 && lat <= 90;
    }
Esempio n. 22
0
 bool GeoParser::parseLine(const BSONObj& obj, LineWithCRS* out) {
     vector<S2Point> vertices;
     if (!parsePoints(obj.getFieldDotted(GEOJSON_COORDINATES).Array(), &vertices)) {
         return false;
     }
     eraseDuplicatePoints(&vertices);
     out->line.Init(vertices);
     out->crs = SPHERE;
     return true;
 }
Esempio n. 23
0
    bool ShardKeyPattern::hasShardKey( const BSONObj& obj ) const {
        /* this is written s.t. if obj 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) {
            if(obj.getFieldDotted(it->c_str()).eoo())
                return false;
        }
        return true;
    }
    bool GeoParser::isGeoJSONLineString(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_LINESTRING != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinateArray = coordElt.Array();
        if (coordinateArray.size() < 2) { return false; }
        if (!isArrayOfCoordinates(coordinateArray)) { return false; }
        vector<S2Point> vertices;
        parsePoints(obj.getFieldDotted(GEOJSON_COORDINATES).Array(), &vertices);
        eraseDuplicatePoints(&vertices);
        return S2Polyline::IsValid(vertices);
    }
Esempio n. 25
0
    static bool isGeoJSONPoint(const BSONObj& obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_POINT != type.String()) { return false; }

        if (!GeoParser::crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (coordinates.size() != 2) { return false; }
        if (!coordinates[0].isNumber() || !coordinates[1].isNumber()) { return false; }
        // For now, we assume all GeoJSON must be within WGS84 - this may change
        double lat = coordinates[1].Number();
        double lng = coordinates[0].Number();
        return isValidLngLat(lng, lat);
    }
Esempio n. 26
0
 // Copy a range of documents to the local oplog.refs collection
 static void copyOplogRefsRange(OplogReader &r, OID oid) {
     shared_ptr<DBClientCursor> c = r.getOplogRefsCursor(oid);
     Client::ReadContext ctx(rsOplogRefs);
     while (c->more()) {
         BSONObj b = c->next();
         BSONElement eOID = b.getFieldDotted("_id.oid");
         if (oid != eOID.OID()) {
             break;
         }
         LOG(6) << "copyOplogRefsRange " << b << endl;
         writeEntryToOplogRefs(b);
     }
 }
Esempio n. 27
0
    bool GeoParser::isGeometryCollection(const BSONObj &obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_GEOMETRY_COLLECTION != type.String()) { return false; }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_GEOMETRIES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (0 == coordinates.size()) { return false; }

        for (size_t i = 0; i < coordinates.size(); ++i) {
            if (coordinates[i].eoo() || (Object != coordinates[i].type())) { return false; }
            BSONObj obj = coordinates[i].Obj();
            if (!isGeoJSONPoint(obj) && !isLine(obj) && !isGeoJSONPolygon(obj)
                && !isMultiPoint(obj) && !isMultiPolygon(obj) && !isMultiLine(obj)) {
                return false;
            }
        }

        return true;
    }
Esempio n. 28
0
    bool GeoParser::isMultiPolygon(const BSONObj &obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_MULTI_POLYGON != type.String()) { return false; }

        if (!crsIsOK(obj)) {
            warning() << "Invalid CRS: " << obj.toString() << endl;
            return false;
        }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_COORDINATES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (0 == coordinates.size()) { return false; }
        for (size_t i = 0; i < coordinates.size(); ++i) {
            if (coordinates[i].eoo() || (Array != coordinates[i].type())) { return false; }
            if (!isGeoJSONPolygonCoordinates(coordinates[i].Array())) { return false; }
        }

        return true;
    }
Esempio n. 29
0
 void rollbackRefOp(BSONObj entry) {
     OID oid = entry["ref"].OID();
     LOG(3) << "rollback ref " << entry << " oid " << oid << endl;
     long long seq = LLONG_MAX;
     while (1) {
         BSONObj currEntry;
         {
             LOCK_REASON(lockReason, "repl: rolling back entry from oplog.refs");
             Client::ReadContext ctx(rsOplogRefs, lockReason);
             verify(rsOplogRefsDetails != NULL);
             shared_ptr<Cursor> c(
                 Cursor::make(
                     rsOplogRefsDetails,
                     rsOplogRefsDetails->getPKIndex(),
                     KeyPattern::toKeyFormat(BSON( "_id" << BSON("oid" << oid << "seq" << seq))), // right endpoint
                     KeyPattern::toKeyFormat(BSON( "_id" << BSON("oid" << oid << "seq" << 0))), // left endpoint
                     false,
                     -1 // direction
                     )
                 );
             if (c->ok()) {
                 currEntry = c->current().copy();
             }
             else {
                 break;
             }
         }
         BSONElement e = currEntry.getFieldDotted("_id.seq");
         seq = e.Long();
         BSONElement eOID = currEntry.getFieldDotted("_id.oid");
         if (oid != eOID.OID()) {
             break;
         }
         LOG(3) << "apply " << currEntry << " seq=" << seq << endl;
         rollbackOps(currEntry["ops"].Array());
         // decrement seq so next query gets the next value
         seq--;
     }
 }
Esempio n. 30
0
    /* return has eoo() true if no match
       supports "." notation to reach into embedded objects
    */
    BSONElement BSONObj::getFieldDotted(const char *name) const {
        BSONElement e = getField( name );
        if ( e.eoo() ) {
            const char *p = strchr(name, '.');
            if ( p ) {
                string left(name, p-name);
                BSONObj sub = getObjectField(left.c_str());
                return sub.isEmpty() ? nullElement : sub.getFieldDotted(p+1);
            }
        }

        return e;
    }