int mongo_cursor_next( mongo_cursor *cursor ) { char *next_object; char *message_end; if( ! ( cursor->flags & MONGO_CURSOR_QUERY_SENT ) ) mongo_cursor_op_query( cursor ); if( !cursor->reply ) return MONGO_ERROR; /* no data */ if ( cursor->reply->fields.num == 0 ) { /* Special case for tailable cursors. */ if( cursor->reply->fields.cursorID ) { if( ( mongo_cursor_get_more( cursor ) != MONGO_OK ) || cursor->reply->fields.num == 0 ) { return MONGO_ERROR; } } else return MONGO_ERROR; } /* first */ if ( cursor->current.data == NULL ) { bson_init_data( &cursor->current, &cursor->reply->objs ); return MONGO_OK; } next_object = cursor->current.data + bson_size( &cursor->current ); message_end = ( char * )cursor->reply + cursor->reply->head.len; if ( next_object >= message_end ) { if( mongo_cursor_get_more( cursor ) != MONGO_OK ) return MONGO_ERROR; /* If there's still a cursor id, then the message should be pending. */ if( cursor->reply->fields.num == 0 && cursor->reply->fields.cursorID ) { cursor->err = MONGO_CURSOR_PENDING; return MONGO_ERROR; } bson_init_data( &cursor->current, &cursor->reply->objs ); } else { bson_init_data( &cursor->current, next_object ); } return MONGO_OK; }
MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query, const bson *fields, int limit, int skip, int options ) { mongo_cursor *cursor = ( mongo_cursor * )bson_malloc( sizeof( mongo_cursor ) ); mongo_cursor_init( cursor, conn, ns ); cursor->flags |= MONGO_CURSOR_MUST_FREE; mongo_cursor_set_query( cursor, query ); mongo_cursor_set_fields( cursor, fields ); mongo_cursor_set_limit( cursor, limit ); mongo_cursor_set_skip( cursor, skip ); mongo_cursor_set_options( cursor, options ); if( mongo_cursor_op_query( cursor ) == MONGO_OK ) return cursor; else { mongo_cursor_destroy( cursor ); return NULL; } }