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 void bson_iterator_subobject( const bson_iterator *i, bson *sub ) { check_mongo_object( (void*)sub ); check_mongo_object( (void*)i ); bson_init_data( sub, ( char * )bson_iterator_value( i ) ); _bson_reset( sub ); sub->finished = 1; }
bson *bson_empty( bson *obj ) { static char *data = "\005\0\0\0\0"; bson_init_data( obj, data ); obj->finished = 1; obj->err = 0; obj->stackPos = 0; return obj; }
void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) { if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) { int code_len; bson_little_endian32( &code_len, bson_iterator_value( i )+4 ); bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) ); } else { bson_empty( scope ); } }
MONGO_EXPORT bson *bson_empty( bson *obj ) { ASSIGN_SIGNATURE(obj, MONGO_SIGNATURE); bson_init_data( obj, emptyData ); obj->finished = 1; obj->err = 0; obj->errstr = NULL; obj->stackPos = 0; return obj; }
MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) { check_mongo_object( (void*)scope ); check_mongo_object( (void*)i ); if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) { int code_len; bson_little_endian32( &code_len, bson_iterator_value( i )+4 ); bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) ); _bson_reset( scope ); scope->finished = 1; } else { bson_empty( scope ); } }
void bson_iterator_subobject( const bson_iterator *i, bson *sub ) { bson_init_data( sub, ( char * )bson_iterator_value( i ) ); _bson_reset( sub ); sub->finished = 1; }
static int mongo_cursor_op_query( mongo_cursor *cursor ) { int res; bson empty; char *data; mongo_message *mm; bson temp; bson_iterator it; /* Clear any errors. */ bson_free( cursor->conn->lasterrstr ); cursor->conn->lasterrstr = NULL; cursor->conn->lasterrcode = 0; cursor->conn->err = 0; cursor->err = 0; /* Set up default values for query and fields, if necessary. */ if( ! cursor->query ) cursor->query = bson_empty( &empty ); else if( mongo_cursor_bson_valid( cursor, cursor->query ) != MONGO_OK ) return MONGO_ERROR; if( ! cursor->fields ) cursor->fields = bson_empty( &empty ); else if( mongo_cursor_bson_valid( cursor, cursor->fields ) != MONGO_OK ) return MONGO_ERROR; mm = mongo_message_create( 16 + /* header */ 4 + /* options */ strlen( cursor->ns ) + 1 + /* ns */ 4 + 4 + /* skip,return */ bson_size( cursor->query ) + bson_size( cursor->fields ) , 0 , 0 , MONGO_OP_QUERY ); data = &mm->data; data = mongo_data_append32( data , &cursor->options ); data = mongo_data_append( data , cursor->ns , strlen( cursor->ns ) + 1 ); data = mongo_data_append32( data , &cursor->skip ); data = mongo_data_append32( data , &cursor->limit ); data = mongo_data_append( data , cursor->query->data , bson_size( cursor->query ) ); if ( cursor->fields ) data = mongo_data_append( data , cursor->fields->data , bson_size( cursor->fields ) ); bson_fatal_msg( ( data == ( ( char * )mm ) + mm->head.len ), "query building fail!" ); res = mongo_message_send( cursor->conn , mm ); if( res != MONGO_OK ) { return MONGO_ERROR; } res = mongo_read_response( cursor->conn, ( mongo_reply ** )&( cursor->reply ) ); if( res != MONGO_OK ) { return MONGO_ERROR; } if( cursor->reply->fields.num == 1 ) { bson_init_data( &temp, &cursor->reply->objs ); if( bson_find( &it, &temp, "$err" ) ) { cursor->conn->lasterrstr = (char *)bson_malloc( bson_iterator_string_len( &it ) ); strcpy( cursor->conn->lasterrstr, bson_iterator_string( &it ) ); bson_find( &it, &temp, "code" ); cursor->conn->lasterrcode = bson_iterator_int( &it ); cursor->err = MONGO_CURSOR_QUERY_FAIL; return MONGO_ERROR; } } cursor->seen += cursor->reply->fields.num; cursor->flags |= MONGO_CURSOR_QUERY_SENT; return MONGO_OK; }
int bson_init_finished_data( bson *b, char *data ) { bson_init_data( b, data ); b->finished = 1; return BSON_OK; }