static void test_read_prefs_mongos_secondary (void) { mongoc_read_prefs_t *read_prefs; read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); _test_read_prefs ( READ_PREF_TEST_MONGOS, read_prefs, "{}", "{'$query': {}, '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK, "{'$query': {'find': 'test', 'filter': {}}," " '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs ( READ_PREF_TEST_MONGOS, read_prefs, "{'a': 1}", "{'$query': {'a': 1}, '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK, "{'$query': {'find': 'test', 'filter': {'a': 1}}," " '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs ( READ_PREF_TEST_MONGOS, read_prefs, "{'$query': {'a': 1}}", "{'$query': {'a': 1}, '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK, "{'$query': {'find': 'test', 'filter': {'a': 1}}," " '$readPreference': {'mode': 'secondary'}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
void mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) { mongoc_topology_t *topology; mongoc_server_description_t *selected_server; mongoc_read_prefs_t *read_prefs; uint32_t server_id = 0; topology = client->topology; read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); mongoc_mutex_lock (&topology->mutex); /* see if there's a known writable server - do no I/O or retries */ selected_server = mongoc_topology_description_select(&topology->description, MONGOC_SS_WRITE, read_prefs, 15); if (selected_server) { server_id = selected_server->id; } mongoc_mutex_unlock (&topology->mutex); if (server_id) { _mongoc_client_kill_cursor (client, selected_server->id, cursor_id); } else { MONGOC_INFO ("No server available for mongoc_client_kill_cursor"); } mongoc_read_prefs_destroy (read_prefs); }
static void test_read_prefs_standalone_primary (void) { mongoc_read_prefs_t *read_prefs; /* Server Selection Spec: for topology type single and server types other * than mongos, "clients MUST always set the slaveOK wire protocol flag on * reads to ensure that any server type can handle the request." * */ read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); _test_read_prefs (READ_PREF_TEST_STANDALONE, read_prefs, "{}", "{}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs (READ_PREF_TEST_STANDALONE, read_prefs, "{'a': 1}", "{'a': 1}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {'a': 1}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
int main (int argc, char *argv[]) { mongoc_read_prefs_t *read_prefs; mongoc_client_t *client; mongoc_uri_t *uri; if (argc < 2) { fprintf(stderr, "usage: %s mongodb://...\n", argv[0]); return EXIT_FAILURE; } uri = mongoc_uri_new(argv[1]); if (!uri) { fprintf(stderr, "Invalid URI: \"%s\"\n", argv[1]); return EXIT_FAILURE; } signal(SIGUSR1, sighandler); signal(SIGUSR2, sighandler); client = mongoc_client_new_from_uri(uri); read_prefs = mongoc_read_prefs_new(MONGOC_READ_SECONDARY); mongoc_client_set_read_prefs(client, read_prefs); mongoc_read_prefs_destroy(read_prefs); test_secondary(client); mongoc_client_destroy(client); mongoc_uri_destroy(uri); return EXIT_SUCCESS; }
static void test_read_prefs_standalone_tags (void) { bson_t b = BSON_INITIALIZER; mongoc_read_prefs_t *read_prefs; bson_append_utf8 (&b, "dc", 2, "ny", 2); read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); mongoc_read_prefs_add_tag (read_prefs, &b); mongoc_read_prefs_add_tag (read_prefs, NULL); _test_read_prefs (READ_PREF_TEST_STANDALONE, read_prefs, "{}", "{}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs (READ_PREF_TEST_STANDALONE, read_prefs, "{'a': 1}", "{'a': 1}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {'a': 1}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
static void test_mongoc_client_command_secondary (void) { mongoc_client_t *client; mongoc_cursor_t *cursor; mongoc_read_prefs_t *read_prefs; bson_t cmd = BSON_INITIALIZER; client = mongoc_client_new (gTestUri); assert (client); BSON_APPEND_INT32 (&cmd, "invalid_command_here", 1); read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED); suppress_one_message (); cursor = mongoc_client_command (client, "admin", MONGOC_QUERY_NONE, 0, 1, 0, &cmd, NULL, read_prefs); mongoc_read_prefs_destroy (read_prefs); /* ensure we detected this must go to primary */ assert (cursor->redir_primary); mongoc_cursor_destroy (cursor); mongoc_client_destroy (client); bson_destroy (&cmd); }
void mongoc_database_destroy (mongoc_database_t *database) { ENTRY; BSON_ASSERT (database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (database->read_concern) { mongoc_read_concern_destroy(database->read_concern); database->read_concern = NULL; } if (database->write_concern) { mongoc_write_concern_destroy(database->write_concern); database->write_concern = NULL; } bson_free(database); EXIT; }
static void test_read_prefs_secondary_rssecondary (void) { mongoc_read_prefs_t *read_prefs; read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); _test_read_prefs (READ_PREF_TEST_SECONDARY, read_prefs, "{}", "{}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs (READ_PREF_TEST_SECONDARY, read_prefs, "{'a': 1}", "{'a': 1}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {'a': 1}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
static void test_read_prefs_mongos_primary (void) { mongoc_read_prefs_t *read_prefs; read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); _test_read_prefs (READ_PREF_TEST_MONGOS, read_prefs, "{}", "{}", MONGOC_QUERY_NONE, "{'find': 'test', 'filter': {}}", MONGOC_QUERY_NONE); _test_read_prefs (READ_PREF_TEST_MONGOS, read_prefs, "{'a': 1}", "{'a': 1}", MONGOC_QUERY_NONE, "{'find': 'test', 'filter': {'a': 1}}", MONGOC_QUERY_NONE); mongoc_read_prefs_destroy (read_prefs); }
static void test_read_prefs_mongos_secondary_preferred (void) { mongoc_read_prefs_t *read_prefs; read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); /* $readPreference not sent, only slaveOk */ _test_read_prefs (READ_PREF_TEST_MONGOS, read_prefs, "{}", "{}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs (READ_PREF_TEST_MONGOS, read_prefs, "{'a': 1}", "{'a': 1}", MONGOC_QUERY_SLAVE_OK, "{'find': 'test', 'filter': {'a': 1}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
SOFT_BEGIN_NAMESPACE MONGO_BEGIN_NAMESPACE static void readPrefsDeleter(mongoc_read_prefs_t *ptr) { mongoc_read_prefs_destroy (ptr); }
static void test_read_prefs_mongos_tags (void) { bson_t b = BSON_INITIALIZER; mongoc_read_prefs_t *read_prefs; bson_append_utf8 (&b, "dc", 2, "ny", 2); read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY_PREFERRED); mongoc_read_prefs_add_tag (read_prefs, &b); mongoc_read_prefs_add_tag (read_prefs, NULL); _test_read_prefs ( READ_PREF_TEST_MONGOS, read_prefs, "{}", "{'$query': {}, '$readPreference': {'mode': 'secondaryPreferred'," " 'tags': [{'dc': 'ny'}, {}]}}", MONGOC_QUERY_SLAVE_OK, "{'$query': {'find': 'test', 'filter': {}}," " '$readPreference': {'mode': 'secondaryPreferred'," " 'tags': [{'dc': 'ny'}, {}]}}", MONGOC_QUERY_SLAVE_OK); _test_read_prefs ( READ_PREF_TEST_MONGOS, read_prefs, "{'a': 1}", "{'$query': {'a': 1}," " '$readPreference': {'mode': 'secondaryPreferred'," " 'tags': [{'dc': 'ny'}, {}]}}", MONGOC_QUERY_SLAVE_OK, "{'$query': {'find': 'test', 'filter': {}}," " '$readPreference': {'mode': 'secondaryPreferred'," " 'tags': [{'dc': 'ny'}, {}]}}", MONGOC_QUERY_SLAVE_OK); mongoc_read_prefs_destroy (read_prefs); }
void mongoc_transaction_opts_set_read_prefs (mongoc_transaction_opt_t *opts, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (opts); mongoc_read_prefs_destroy (opts->read_prefs); opts->read_prefs = mongoc_read_prefs_copy (read_prefs); }
/* direct connection to a secondary requires read pref primaryPreferred to * avoid "not master" error from server */ static void _test_op_msg_direct_connection (bool is_mongos, test_op_msg_direct_fn_t fn, const char *expected_cmd) { mock_server_t *server; mongoc_client_t *client; mongoc_collection_t *collection; mongoc_read_prefs_t *prefs = NULL; mongoc_cursor_t *cursor; const bson_t *doc; bson_t *cmd; future_t *future; request_t *request; const char *reply; int i; if (is_mongos) { server = mock_mongos_new (WIRE_VERSION_OP_MSG); } else { server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG); } mock_server_auto_endsessions (server); mock_server_run (server); client = mongoc_client_new_from_uri (mock_server_get_uri (server)); collection = mongoc_client_get_collection (client, "db", "collection"); for (i = 0; i < 2; i++) { if (i == 1) { /* user-supplied read preference primary makes no difference */ prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); } cursor = fn (collection, prefs); future = future_cursor_next (cursor, &doc); cmd = tmp_bson (expected_cmd); request = mock_server_receives_msg (server, 0, cmd); reply = "{'ok': 1," " 'cursor': {" " 'id': 0," " 'ns': 'db.collection'," " 'firstBatch': [{'a': 1}]}}"; mock_server_replies_simple (request, reply); BSON_ASSERT (future_get_bool (future)); future_destroy (future); request_destroy (request); mongoc_cursor_destroy (cursor); mongoc_read_prefs_destroy (prefs); /* null ok */ } mongoc_collection_destroy (collection); mongoc_client_destroy (client); mock_server_destroy (server); }
void mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, const mongoc_read_prefs_t *prefs) { BSON_ASSERT (uri); BSON_ASSERT (prefs); mongoc_read_prefs_destroy (uri->read_prefs); uri->read_prefs = mongoc_read_prefs_copy (prefs); }
/** * mongoc_database_has_collection: * @database: (in): A #mongoc_database_t. * @name: (in): The name of the collection to check for. * @error: (out) (allow-none): A location for a #bson_error_t, or %NULL. * * Checks to see if a collection exists within the database on the MongoDB * server. * * This will return %false if their was an error communicating with the * server, or if the collection does not exist. * * If @error is provided, it will first be zeroed. Upon error, error.domain * will be set. * * Returns: %true if @name exists, otherwise %false. @error may be set. */ bool mongoc_database_has_collection (mongoc_database_t *database, const char *name, bson_error_t *error) { mongoc_collection_t *collection; mongoc_read_prefs_t *read_prefs; mongoc_cursor_t *cursor; const bson_t *doc; bson_iter_t iter; bool ret = false; const char *cur_name; bson_t q = BSON_INITIALIZER; char ns[140]; ENTRY; BSON_ASSERT (database); BSON_ASSERT (name); if (error) { memset (error, 0, sizeof *error); } bson_snprintf (ns, sizeof ns, "%s.%s", database->name, name); ns[sizeof ns - 1] = '\0'; read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); collection = mongoc_client_get_collection (database->client, database->name, "system.namespaces"); cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, &q, NULL, read_prefs); while (!mongoc_cursor_error (cursor, error) && mongoc_cursor_more (cursor)) { while (mongoc_cursor_next (cursor, &doc) && bson_iter_init_find (&iter, doc, "name") && BSON_ITER_HOLDS_UTF8 (&iter)) { cur_name = bson_iter_utf8(&iter, NULL); if (!strcmp(cur_name, ns)) { ret = true; GOTO(cleanup); } } } cleanup: mongoc_cursor_destroy (cursor); mongoc_collection_destroy (collection); mongoc_read_prefs_destroy (read_prefs); RETURN(ret); }
static void txn_opts_cleanup (mongoc_transaction_opt_t *opts) { /* null inputs are ok */ mongoc_read_concern_destroy (opts->read_concern); mongoc_write_concern_destroy (opts->write_concern); mongoc_read_prefs_destroy (opts->read_prefs); /* prepare opts for reuse */ opts->read_concern = NULL; opts->write_concern = NULL; opts->read_prefs = NULL; }
/* test that we add readConcern only inside $query, not outside it too */ static void test_mongos_read_concern (void) { mock_server_t *server; mongoc_client_t *client; mongoc_collection_t *collection; mongoc_read_prefs_t *prefs; mongoc_cursor_t *cursor; const bson_t *doc; future_t *future; request_t *request; server = mock_mongos_new (WIRE_VERSION_READ_CONCERN); mock_server_run (server); client = mongoc_client_new_from_uri (mock_server_get_uri (server)); collection = mongoc_client_get_collection (client, "test", "test"); prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); cursor = mongoc_collection_find_with_opts ( collection, tmp_bson ("{'a': 1}"), tmp_bson ("{'readConcern': {'level': 'foo'}}"), prefs); future = future_cursor_next (cursor, &doc); request = mock_server_receives_command ( server, "test", MONGOC_QUERY_SLAVE_OK, "{" " '$query': {" " 'find': 'test', 'filter': {}, 'readConcern': {'level': 'foo'}" " }," " '$readPreference': {" " 'mode': 'secondary'" " }," " 'readConcern': {'$exists': false}" "}"); mock_server_replies_to_find ( request, MONGOC_QUERY_SLAVE_OK, 0, 1, "db.collection", "{}", true); /* mongoc_cursor_next returned true */ BSON_ASSERT (future_get_bool (future)); request_destroy (request); future_destroy (future); mongoc_cursor_destroy (cursor); mongoc_read_prefs_destroy (prefs); mongoc_collection_destroy (collection); mongoc_client_destroy (client); mock_server_destroy (server); }
mongoc_cursor_t * mongoc_database_find_collections (mongoc_database_t *database, const bson_t *filter, bson_error_t *error) { mongoc_cursor_t *cursor; mongoc_read_prefs_t *read_prefs; bson_t cmd = BSON_INITIALIZER; bson_t child; bson_error_t lerror; BSON_ASSERT (database); BSON_APPEND_INT32 (&cmd, "listCollections", 1); if (filter) { BSON_APPEND_DOCUMENT (&cmd, "filter", filter); BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child); bson_append_document_end (&cmd, &child); } read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = _mongoc_cursor_new (database->client, database->name, MONGOC_QUERY_SLAVE_OK, 0, 0, 0, true, NULL, NULL, NULL, NULL); _mongoc_cursor_cursorid_init (cursor, &cmd); if (_mongoc_cursor_cursorid_prime (cursor)) { /* intentionally empty */ } else { if (mongoc_cursor_error (cursor, &lerror)) { if (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { /* We are talking to a server that doesn' support listCollections. */ /* clear out the error. */ memset (&lerror, 0, sizeof lerror); /* try again with using system.namespaces */ mongoc_cursor_destroy (cursor); cursor = _mongoc_database_find_collections_legacy ( database, filter, error); } else if (error) { memcpy (error, &lerror, sizeof *error); } } } bson_destroy (&cmd); mongoc_read_prefs_destroy (read_prefs); return cursor; }
void mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs) { bson_return_if_fail (client); if (read_prefs != client->read_prefs) { if (client->read_prefs) { mongoc_read_prefs_destroy(client->read_prefs); } client->read_prefs = read_prefs ? mongoc_read_prefs_copy(read_prefs) : mongoc_read_prefs_new(MONGOC_READ_PRIMARY); } }
void mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (client); if (read_prefs != client->read_prefs) { if (client->read_prefs) { mongoc_read_prefs_destroy(client->read_prefs); } client->read_prefs = read_prefs ? mongoc_read_prefs_copy(read_prefs) : mongoc_read_prefs_new(MONGOC_READ_PRIMARY); } }
void mongoc_database_set_read_prefs (mongoc_database_t *database, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (read_prefs) { database->read_prefs = mongoc_read_prefs_copy(read_prefs); } }
void mongoc_database_set_read_prefs (mongoc_database_t *database, const mongoc_read_prefs_t *read_prefs) { bson_return_if_fail(database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (read_prefs) { database->read_prefs = mongoc_read_prefs_copy(read_prefs); } }
void mongoc_client_destroy (mongoc_client_t *client) { if (client) { #ifdef MONGOC_ENABLE_SSL bson_free (client->pem_subject); #endif mongoc_write_concern_destroy (client->write_concern); mongoc_read_prefs_destroy (client->read_prefs); _mongoc_cluster_destroy (&client->cluster); mongoc_uri_destroy (client->uri); bson_free (client); mongoc_counter_clients_active_dec (); mongoc_counter_clients_disposed_inc (); } }
bson_t * mongoc_database_get_collection_info (mongoc_database_t *database, const bson_t *filter, bson_error_t *error) { mongoc_read_prefs_t *read_prefs; bson_t *reply = bson_new(); bson_t cmd = BSON_INITIALIZER; bool cmd_success; BSON_ASSERT (database); BSON_APPEND_INT32 (&cmd, "listCollections", 1); if (filter) { BSON_APPEND_DOCUMENT (&cmd, "filter", filter); } read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cmd_success = mongoc_database_command_simple (database, &cmd, read_prefs, reply, error); if (cmd_success) { /* intentionally empty */ } else if (error->code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { bson_destroy (reply); /* We are talking to a server that doesn' support listCollections. */ /* clear out the error. */ error->code = 0; error->domain = 0; /* try again with using system.namespaces */ reply = _mongoc_database_get_collection_info_legacy (database, filter, error); } else { /* network error */ bson_destroy (reply); reply = NULL; } bson_destroy (&cmd); mongoc_read_prefs_destroy (read_prefs); return reply; }
void mongoc_change_stream_destroy (mongoc_change_stream_t *stream) { if (!stream) { return; } bson_destroy (&stream->pipeline_to_append); bson_destroy (&stream->resume_token); bson_destroy (stream->full_document); bson_destroy (&stream->err_doc); _mongoc_change_stream_opts_cleanup (&stream->opts); mongoc_cursor_destroy (stream->cursor); mongoc_client_session_destroy (stream->implicit_session); mongoc_read_prefs_destroy (stream->read_prefs); mongoc_read_concern_destroy (stream->read_concern); bson_free (stream); }
void mongoc_uri_destroy (mongoc_uri_t *uri) { if (uri) { mongoc_host_list_destroy_all (uri->hosts); bson_free(uri->str); bson_free(uri->database); bson_free(uri->username); bson_destroy(&uri->options); bson_destroy(&uri->credentials); mongoc_read_prefs_destroy(uri->read_prefs); mongoc_write_concern_destroy(uri->write_concern); if (uri->password) { bson_zero_free(uri->password, strlen(uri->password)); } bson_free(uri); } }
void mongoc_database_destroy (mongoc_database_t *database) { ENTRY; bson_return_if_fail(database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (database->write_concern) { mongoc_write_concern_destroy(database->write_concern); database->write_concern = NULL; } bson_free(database); EXIT; }
void _mongoc_cursor_destroy (mongoc_cursor_t *cursor) { ENTRY; bson_return_if_fail(cursor); if (cursor->in_exhaust) { cursor->client->in_exhaust = FALSE; if (!cursor->done) { _mongoc_cluster_disconnect_node ( &cursor->client->cluster, &cursor->client->cluster.nodes[cursor->hint - 1]); } } else if (cursor->rpc.reply.cursor_id) { _mongoc_cursor_kill_cursor(cursor, cursor->rpc.reply.cursor_id); } if (cursor->reader) { bson_reader_destroy(cursor->reader); cursor->reader = NULL; } bson_destroy(&cursor->query); bson_destroy(&cursor->fields); _mongoc_buffer_destroy(&cursor->buffer); mongoc_read_prefs_destroy(cursor->read_prefs); bson_free(cursor); mongoc_counter_cursors_active_dec(); mongoc_counter_cursors_disposed_inc(); EXIT; }
/* Uses old way of querying system.namespaces. */ mongoc_cursor_t * _mongoc_database_find_collections_legacy (mongoc_database_t *database, const bson_t *filter, bson_error_t *error) { mongoc_collection_t *col; mongoc_cursor_t *cursor = NULL; mongoc_read_prefs_t *read_prefs; uint32_t dbname_len; bson_t legacy_filter; bson_iter_t iter; const char *col_filter; bson_t q = BSON_INITIALIZER; mongoc_database_find_collections_legacy_ctx_t *ctx; BSON_ASSERT (database); col = mongoc_client_get_collection (database->client, database->name, "system.namespaces"); BSON_ASSERT (col); dbname_len = (uint32_t)strlen (database->name); ctx = bson_malloc (sizeof (*ctx)); ctx->dbname = database->name; ctx->dbname_len = dbname_len; /* Filtering on name needs to be handled differently for old servers. */ if (filter && bson_iter_init_find (&iter, filter, "name")) { bson_string_t *buf; /* on legacy servers, this must be a string (i.e. not a regex) */ if (!BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID_FILTER_TYPE, "On legacy servers, a filter on name can only be a string."); goto cleanup_filter; } BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); col_filter = bson_iter_utf8 (&iter, NULL); bson_init (&legacy_filter); bson_copy_to_excluding_noinit (filter, &legacy_filter, "name", NULL); /* We must db-qualify filters on name. */ buf = bson_string_new (database->name); bson_string_append_c (buf, '.'); bson_string_append (buf, col_filter); BSON_APPEND_UTF8 (&legacy_filter, "name", buf->str); bson_string_free (buf, true); filter = &legacy_filter; } read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = mongoc_collection_find (col, MONGOC_QUERY_NONE, 0, 0, 0, filter ? filter : &q, NULL, read_prefs); _mongoc_cursor_transform_init ( cursor, _mongoc_database_find_collections_legacy_filter, _mongoc_database_find_collections_legacy_mutate, &bson_free, ctx); mongoc_read_prefs_destroy (read_prefs); cleanup_filter: mongoc_collection_destroy (col); return cursor; }