SEXP mongo_get_databases(SEXP mongo_conn) { mongo* conn = _checkMongo(mongo_conn); bson out; if (mongo_simple_int_command(conn, "admin", "listDatabases", 1, &out) != MONGO_OK) { bson_destroy(&out); return R_NilValue; } bson_iterator it, databases, database; bson_iterator_init(&it, &out); bson_iterator_next(&it); bson_iterator_subiterator(&it, &databases); int count = 0; while (bson_iterator_next(&databases)) { bson_iterator_subiterator(&databases, &database); bson_iterator_next(&database); const char* name = bson_iterator_string(&database); if (strcmp(name, "admin") != 0 && strcmp(name, "local") != 0) count++; } SEXP ret; PROTECT(ret = allocVector(STRSXP, count)); bson_iterator_subiterator(&it, &databases); int i = 0; while (bson_iterator_next(&databases)) { bson_iterator_subiterator(&databases, &database); bson_iterator_next(&database); const char* name = bson_iterator_string(&database); if (strcmp(name, "admin") != 0 && strcmp(name, "local") != 0) SET_STRING_ELT(ret, i++, mkChar(name)); } bson_destroy(&out); UNPROTECT(1); return ret; }
/* Find out whether the current connected node is master, and * verify that the node's replica set name matched the provided name */ static int mongo_replset_check_host( mongo *conn ) { bson out; bson_iterator it; bson_bool_t ismaster = 0; const char *set_name; out.data = NULL; if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) { if( bson_find( &it, &out, "ismaster" ) ) ismaster = bson_iterator_bool( &it ); if( bson_find( &it, &out, "setName" ) ) { set_name = bson_iterator_string( &it ); if( strcmp( set_name, conn->replset->name ) != 0 ) { bson_destroy( &out ); conn->err = MONGO_CONN_BAD_SET_NAME; return MONGO_ERROR; } } } bson_destroy( &out ); if( ismaster ) { conn->replset->primary_connected = 1; } else { mongo_close_socket( conn->sock ); } return MONGO_OK; }
/* Find out whether the current connected node is master, and * verify that the node's replica set name matched the provided name */ static int mongo_replset_check_host( mongo_connection* conn ) { bson out; bson_iterator it; bson_bool_t ismaster = 0; const char* set_name; out.data = NULL; out.owned = 1; if (mongo_simple_int_command(conn, "admin", "ismaster", 1, &out)) { if( bson_find(&it, &out, "ismaster") ) ismaster = bson_iterator_bool( &it ); if( bson_find( &it, &out, "setName" ) ) { set_name = bson_iterator_string( &it ); if( strcmp( set_name, conn->replset->name ) != 0 ) { return mongo_conn_bad_set_name; } } } bson_destroy( &out ); if(ismaster) { conn->replset->primary_connected = 1; } else { mongo_close_socket( conn->sock ); } return 0; }
MONGO_EXPORT int mongo_check_connection( mongo *conn ) { if( ! conn->connected ) return MONGO_ERROR; if( mongo_simple_int_command( conn, "admin", "ping", 1, NULL ) == MONGO_OK ) return MONGO_OK; else return MONGO_ERROR; }
bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) { bson from_db; bson cmd; bson out; const char *nonce; bson_bool_t success = 0; mongo_md5_state_t st; mongo_md5_byte_t digest[16]; char hex_digest[33]; if( mongo_simple_int_command( conn, db, "getnonce", 1, &from_db ) == MONGO_OK ) { bson_iterator it; bson_find( &it, &from_db, "nonce" ); nonce = bson_iterator_string( &it ); } else { return MONGO_ERROR; } mongo_pass_digest( user, pass, hex_digest ); mongo_md5_init( &st ); mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, strlen( nonce ) ); mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, strlen( user ) ); mongo_md5_append( &st, ( const mongo_md5_byte_t * )hex_digest, 32 ); mongo_md5_finish( &st, digest ); digest2hex( digest, hex_digest ); bson_init( &cmd ); bson_append_int( &cmd, "authenticate", 1 ); bson_append_string( &cmd, "user", user ); bson_append_string( &cmd, "nonce", nonce ); bson_append_string( &cmd, "key", hex_digest ); bson_finish( &cmd ); bson_destroy( &from_db ); /*bson_init( &from_db ); */ if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) { bson_iterator it; if( bson_find( &it, &out, "ok" ) ) success = bson_iterator_bool( &it ); } bson_destroy( &from_db ); bson_destroy( &cmd ); if( success ) return MONGO_OK; else return MONGO_ERROR; }
static void mongo_replset_check_seed( mongo_connection* conn ) { bson out; bson hosts; const char* data; bson_iterator it; bson_iterator it_sub; const char* host_string; mongo_host_port *host_port = NULL; out.data = NULL; out.owned = 1; hosts.data = NULL; hosts.owned = 1; if( mongo_simple_int_command(conn, "admin", "ismaster", 1, &out) == MONGO_OK ) { if( bson_find( &it, &out, "hosts" ) ) { data = bson_iterator_value( &it ); bson_iterator_init( &it_sub, data ); /* Iterate over host list, adding each host to the * connection's host list. */ while( bson_iterator_next( &it_sub ) ) { host_string = bson_iterator_string( &it_sub ); host_port = bson_malloc( sizeof( mongo_host_port ) ); mongo_parse_host( host_string, host_port ); if( host_port ) { mongo_replset_add_node( &conn->replset->hosts, host_port->host, host_port->port ); free( host_port ); host_port = NULL; } } } } bson_destroy( &out ); bson_destroy( &hosts ); mongo_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; }
MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) { bson out = {NULL,0}; bson_bool_t ismaster = 0; if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) { bson_iterator it; bson_find( &it, &out, "ismaster" ); ismaster = bson_iterator_bool( &it ); } if( realout ) *realout = out; /* transfer of ownership */ else bson_destroy( &out ); return ismaster; }
SEXP mongo_simple_command(SEXP mongo_conn, SEXP db, SEXP cmdstr, SEXP arg) { mongo* conn = _checkMongo(mongo_conn); const char* _db = CHAR(STRING_ELT(db, 0)); const char* _cmdstr = CHAR(STRING_ELT(cmdstr, 0)); bson out; int success; if (TYPEOF(arg) == STRSXP) success = (mongo_simple_str_command(conn, _db, _cmdstr, CHAR(STRING_ELT(arg, 0)), &out) == MONGO_OK); else success = (mongo_simple_int_command(conn, _db, _cmdstr, asInteger(arg), &out) == MONGO_OK); if (!success) { return R_NilValue; } SEXP ret = _mongo_bson_create(&out); bson_destroy(&out); UNPROTECT(3); return ret; }
static bson_bool_t mongodb_cmd_ping(mongo_connection *conn, const char *db) { bson out; bson_bool_t res; bson_iterator it; memset(&out, 0, sizeof(bson)); res = mongo_simple_int_command(conn, db, "ping", 1, &out); if (res) { if (bson_find(&it, &out, "ok") == bson_eoo) { res = 0; } else { res = bson_iterator_bool(&it); } } bson_destroy(&out); return res; }
static int mongo_check_is_master( mongo *conn ) { bson out; bson_iterator it; bson_bool_t ismaster = 0; out.data = NULL; if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) { if( bson_find( &it, &out, "ismaster" ) ) ismaster = bson_iterator_bool( &it ); } else { return MONGO_ERROR; } bson_destroy( &out ); if( ismaster ) return MONGO_OK; else { conn->err = MONGO_CONN_NOT_MASTER; return MONGO_ERROR; } }
static int mongo_cmd_get_error_helper( mongo *conn, const char *db, bson *realout, const char *cmdtype ) { bson out = {NULL,0}; bson_bool_t haserror = 0; /* Reset last error codes. */ conn->lasterrcode = 0; bson_free( conn->lasterrstr ); conn->lasterrstr = NULL; /* If there's an error, store its code and string in the connection object. */ if( mongo_simple_int_command( conn, db, cmdtype, 1, &out ) == MONGO_OK ) { bson_iterator it; haserror = ( bson_find( &it, &out, "err" ) != BSON_NULL ); if( haserror ) { conn->lasterrstr = ( char * )bson_malloc( bson_iterator_string_len( &it ) ); if( conn->lasterrstr ) { strcpy( conn->lasterrstr, bson_iterator_string( &it ) ); } if( bson_find( &it, &out, "code" ) != BSON_NULL ) conn->lasterrcode = bson_iterator_int( &it ); } } if( realout ) *realout = out; /* transfer of ownership */ else bson_destroy( &out ); if( haserror ) return MONGO_ERROR; else return MONGO_OK; }
MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db ) { mongo_simple_int_command( conn, db, "reseterror", 1, NULL ); }
MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db ) { return mongo_simple_int_command( conn, db, "dropDatabase", 1, NULL ); }
void mongo_cmd_reset_error(mongo_connection * conn, const char * db){ mongo_simple_int_command(conn, db, "reseterror", 1, NULL); }
int main(){ bson obj; strncpy(opts.host, TEST_SERVER, 255); opts.host[254] = '\0'; opts.port = 27017; if (mongo_connect( conn , &opts )){ printf("failed to connect\n"); exit(1); } /*********************/ ASSERT(!mongo_cmd_get_prev_error(conn, db, NULL)); ASSERT(!mongo_cmd_get_last_error(conn, db, NULL)); ASSERT(!mongo_cmd_get_prev_error(conn, db, &obj)); bson_destroy(&obj); ASSERT(!mongo_cmd_get_last_error(conn, db, &obj)); bson_destroy(&obj); /*********************/ mongo_simple_int_command(conn, db, "forceerror", 1, NULL); ASSERT(mongo_cmd_get_prev_error(conn, db, NULL)); ASSERT(mongo_cmd_get_last_error(conn, db, NULL)); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj)); bson_destroy(&obj); ASSERT(mongo_cmd_get_last_error(conn, db, &obj)); bson_destroy(&obj); /* should clear lasterror but not preverror */ mongo_find_one(conn, ns, bson_empty(&obj), bson_empty(&obj), NULL); ASSERT(mongo_cmd_get_prev_error(conn, db, NULL)); ASSERT(!mongo_cmd_get_last_error(conn, db, NULL)); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj)); bson_destroy(&obj); ASSERT(!mongo_cmd_get_last_error(conn, db, &obj)); bson_destroy(&obj); /*********************/ mongo_cmd_reset_error(conn, db); ASSERT(!mongo_cmd_get_prev_error(conn, db, NULL)); ASSERT(!mongo_cmd_get_last_error(conn, db, NULL)); ASSERT(!mongo_cmd_get_prev_error(conn, db, &obj)); bson_destroy(&obj); ASSERT(!mongo_cmd_get_last_error(conn, db, &obj)); bson_destroy(&obj); return 0; }
int main(){ bson obj; INIT_SOCKETS_FOR_WINDOWS; if (mongo_connect( conn , TEST_SERVER, 27017 )){ printf("failed to connect\n"); exit(1); } /*********************/ ASSERT(mongo_cmd_get_prev_error(conn, db, NULL) == MONGO_OK); ASSERT( conn->lasterrcode == 0 ); ASSERT( conn->lasterrstr == NULL ); ASSERT(mongo_cmd_get_last_error(conn, db, NULL) == MONGO_OK); ASSERT( conn->lasterrcode == 0 ); ASSERT( conn->lasterrstr == NULL ); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj) == MONGO_OK); bson_destroy(&obj); ASSERT(mongo_cmd_get_last_error(conn, db, &obj) == MONGO_OK); bson_destroy(&obj); /*********************/ mongo_simple_int_command(conn, db, "forceerror", 1, NULL); ASSERT(mongo_cmd_get_prev_error(conn, db, NULL) == MONGO_ERROR); ASSERT( conn->lasterrcode == 10038 ); ASSERT( strcmp( (const char*)conn->lasterrstr, "forced error" ) == 0 ); ASSERT(mongo_cmd_get_last_error(conn, db, NULL) == MONGO_ERROR); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj) == MONGO_ERROR); bson_destroy(&obj); ASSERT(mongo_cmd_get_last_error(conn, db, &obj) == MONGO_ERROR); bson_destroy(&obj); /* should clear lasterror but not preverror */ mongo_find_one(conn, ns, bson_empty(&obj), bson_empty(&obj), NULL); ASSERT(mongo_cmd_get_prev_error(conn, db, NULL) == MONGO_ERROR); ASSERT(mongo_cmd_get_last_error(conn, db, NULL) == MONGO_OK); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj) == MONGO_ERROR); bson_destroy(&obj); ASSERT(mongo_cmd_get_last_error(conn, db, &obj) == MONGO_OK); bson_destroy(&obj); /*********************/ mongo_cmd_reset_error(conn, db); ASSERT(mongo_cmd_get_prev_error(conn, db, NULL) == MONGO_OK); ASSERT(mongo_cmd_get_last_error(conn, db, NULL) == MONGO_OK); ASSERT(mongo_cmd_get_prev_error(conn, db, &obj) == MONGO_OK); bson_destroy(&obj); ASSERT(mongo_cmd_get_last_error(conn, db, &obj) == MONGO_OK); bson_destroy(&obj); mongo_cmd_drop_db(conn, db); mongo_destroy(conn); return 0; }
static int mongo_replset_check_seed( mongo_connection* conn ) { bson out; bson hosts; const char* data; bson_iterator it; bson_iterator it_sub; const char* host_string; char* host; int len, idx, port, split; out.data = NULL; out.owned = 1; hosts.data = NULL; hosts.owned = 1; if (mongo_simple_int_command(conn, "admin", "ismaster", 1, &out)) { if( bson_find( &it, &out, "hosts" ) ) { data = bson_iterator_value( &it ); bson_iterator_init( &it_sub, data ); /* Iterate over host list, adding each host to the * connection's host list. */ while( bson_iterator_next( &it_sub ) ) { host_string = bson_iterator_string( &it_sub ); len = split = idx = 0; /* Split the host_port string at the ':' */ while(1) { if( *(host_string + len) == 0) break; if( *(host_string + len) == ':' ) split = len; len++; } /* If 'split' is set, we know the that port exists; * Otherwise, we set the default port. */ if( len > 0 ) { idx = split ? split : len; host = (char *)bson_malloc( idx + 1 ); memcpy( host, host_string, idx ); memcpy( host + idx, "\0", 1 ); if( split ) port = atoi( host_string + idx + 1 ); else port = 27017; mongo_replset_add_node( &conn->replset->hosts, host, port ); } } } } bson_destroy( &out ); bson_destroy( &hosts ); mongo_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; return 0; }