static void test_bool (void) { bson_t bcon, expected; bson_init (&bcon); bson_init (&expected); bson_append_bool (&expected, "foo", -1, 1); BCON_APPEND (&bcon, "foo", BCON_BOOL (1)); bson_eq_bson (&bcon, &expected); bson_reinit (&bcon); bson_reinit (&expected); bson_append_bool (&expected, "foo", -1, 0); BCON_APPEND (&bcon, "foo", BCON_BOOL (0)); bson_eq_bson (&bcon, &expected); bson_destroy (&bcon); bson_destroy (&expected); }
static void test_concat (void) { bson_t bcon, expected, child, child2; bson_init (&bcon); bson_init (&expected); bson_init (&child); bson_init (&child2); bson_append_utf8 (&child, "hello", -1, "world", -1); bson_append_document (&expected, "foo", -1, &child); BCON_APPEND (&bcon, "foo", "{", BCON(&child), "}"); bson_eq_bson (&bcon, &expected); bson_reinit (&bcon); bson_reinit (&expected); bson_reinit (&child); bson_append_utf8 (&child, "0", -1, "bar", -1); bson_append_utf8 (&child, "1", -1, "baz", -1); bson_append_array (&expected, "foo", -1, &child); bson_append_utf8 (&child2, "0", -1, "baz", -1); BCON_APPEND (&bcon, "foo", "[", "bar", BCON(&child2), "]"); bson_eq_bson (&bcon, &expected); bson_destroy (&bcon); bson_destroy (&child); bson_destroy (&child2); bson_destroy (&expected); }
static bool _mongoc_cursor_transform_next (mongoc_cursor_t *cursor, const bson_t **bson) { mongoc_cursor_transform_t *transform; ENTRY; transform = cursor->iface_data; for (;; ) { if (!_mongoc_cursor_next (cursor, bson)) { RETURN (false); } switch (transform->filter (*bson, transform->ctx)) { case MONGO_CURSOR_TRANSFORM_DROP: break; case MONGO_CURSOR_TRANSFORM_PASS: RETURN (true); break; case MONGO_CURSOR_TRANSFORM_MUTATE: bson_reinit (&transform->tmp); transform->mutate (*bson, &transform->tmp, transform->ctx); *bson = &transform->tmp; RETURN (true); break; default: abort (); break; } } }
bool mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error) { bson_t sel = BSON_INITIALIZER; bool ret = false; BSON_ASSERT (file); BSON_APPEND_VALUE (&sel, "_id", &file->files_id); if (!mongoc_collection_delete_one ( file->gridfs->files, &sel, NULL, NULL, error)) { goto cleanup; } bson_reinit (&sel); BSON_APPEND_VALUE (&sel, "files_id", &file->files_id); if (!mongoc_collection_delete_many ( file->gridfs->chunks, &sel, NULL, NULL, error)) { goto cleanup; } ret = true; cleanup: bson_destroy (&sel); return ret; }
int main (int argc, char *argv[]) { bson_json_reader_t *reader; bson_error_t error; const char *filename; bson_t doc = BSON_INITIALIZER; int i; int b; /* * Print program usage if no arguments are provided. */ if (argc == 1) { fprintf (stderr, "usage: %s FILE...\n", argv[0]); return 1; } /* * Process command line arguments expecting each to be a filename. */ for (i = 1; i < argc; i++) { filename = argv[i]; /* * Open the filename provided in command line arguments. */ if (0 == strcmp (filename, "-")) { reader = bson_json_reader_new_from_fd (STDIN_FILENO, false); } else { if (!(reader = bson_json_reader_new_from_file (filename, &error))) { fprintf ( stderr, "Failed to open \"%s\": %s\n", filename, error.message); continue; } } /* * Convert each incoming document to BSON and print to stdout. */ while ((b = bson_json_reader_read (reader, &doc, &error))) { if (b < 0) { fprintf (stderr, "Error in json parsing:\n%s\n", error.message); abort (); } if (fwrite (bson_get_data (&doc), 1, doc.len, stdout) != doc.len) { fprintf (stderr, "Failed to write to stdout, exiting.\n"); exit (1); } bson_reinit (&doc); } bson_json_reader_destroy (reader); bson_destroy (&doc); } return 0; }
int main (int argc, char *argv[]) { int i; int n; int bcon; bson_t bson, foo, bar, baz; bson_init (&bson); if (argc != 3) { fprintf (stderr, "usage: bcon-speed NUM_ITERATIONS [y|n]\n" "\n" " y = perform speed tests with bcon\n" " n = perform speed tests with bson_append\n" "\n"); return EXIT_FAILURE; } assert (argc == 3); n = atoi (argv[1]); bcon = (argv[2][0] == 'y') ? 1 : 0; for (i = 0; i < n; i++) { if (bcon) { BCON_APPEND (&bson, "foo", "{", "bar", "{", "baz", "[", BCON_INT32 (1), BCON_INT32 (2), BCON_INT32 (3), "]", "}", "}"); } else { bson_append_document_begin (&bson, "foo", -1, &foo); bson_append_document_begin (&foo, "bar", -1, &bar); bson_append_array_begin (&bar, "baz", -1, &baz); bson_append_int32 (&baz, "0", -1, 1); bson_append_int32 (&baz, "1", -1, 2); bson_append_int32 (&baz, "2", -1, 3); bson_append_array_end (&bar, &baz); bson_append_document_end (&foo, &bar); bson_append_document_end (&bson, &foo); } bson_reinit (&bson); } bson_destroy (&bson); return 0; }
static void test_mongoc_matcher_in_basic (void) { mongoc_matcher_t *matcher; bson_error_t error; bool r; bson_t *spec; bson_t doc = BSON_INITIALIZER; spec = BCON_NEW ("key", "{", "$in", "[", BCON_INT32 (1), BCON_INT32 (2), BCON_INT32 (3), "]", "}"); matcher = mongoc_matcher_new (spec, &error); r = mongoc_matcher_match (matcher, &doc); ASSERT (!r); bson_reinit (&doc); bson_append_int32 (&doc, "key", 3, 1); r = mongoc_matcher_match (matcher, &doc); ASSERT (r); bson_reinit (&doc); bson_append_int32 (&doc, "key", 3, 2); r = mongoc_matcher_match (matcher, &doc); ASSERT (r); bson_reinit (&doc); bson_append_int32 (&doc, "key", 3, 3); r = mongoc_matcher_match (matcher, &doc); ASSERT (r); bson_reinit (&doc); bson_append_int32 (&doc, "key", 3, 4); r = mongoc_matcher_match (matcher, &doc); ASSERT (!r); bson_destroy (&doc); bson_destroy (spec); mongoc_matcher_destroy (matcher); }
static void test_command (void) { mongoc_database_t *database; mongoc_client_t *client; mongoc_cursor_t *cursor; bson_error_t error; const bson_t *doc; bool r; bson_t cmd = BSON_INITIALIZER; bson_t reply; client = mongoc_client_new (gTestUri); assert (client); database = mongoc_client_get_database (client, "admin"); /* * Test a known working command, "ping". */ bson_append_int32 (&cmd, "ping", 4, 1); cursor = mongoc_database_command (database, MONGOC_QUERY_NONE, 0, 1, 0, &cmd, NULL, NULL); assert (cursor); r = mongoc_cursor_next (cursor, &doc); assert (r); assert (doc); r = mongoc_cursor_next (cursor, &doc); assert (!r); assert (!doc); mongoc_cursor_destroy (cursor); /* * Test a non-existing command to ensure we get the failure. */ bson_reinit (&cmd); bson_append_int32 (&cmd, "a_non_existing_command", -1, 1); r = mongoc_database_command_simple (database, &cmd, NULL, &reply, &error); assert (!r); assert (error.domain == MONGOC_ERROR_QUERY); assert (error.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND); assert (!strcmp ("no such cmd: a_non_existing_command", error.message)); mongoc_database_destroy (database); mongoc_client_destroy (client); bson_destroy (&cmd); }
void reinit() { while (!_stack.empty()) { _stack.pop_back(); } bson_reinit(&_root); _depth = 0; _n = 0; _has_user_key = false; }
static void test_validate (void) { mongoc_collection_t *collection; mongoc_client_t *client; bson_iter_t iter; bson_error_t error; bson_t doc = BSON_INITIALIZER; bson_t opts = BSON_INITIALIZER; bson_t reply; bool r; client = mongoc_client_new (gTestUri); ASSERT (client); collection = get_test_collection (client, "test_validate"); ASSERT (collection); r = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, &doc, NULL, &error); assert (r); BSON_APPEND_BOOL (&opts, "full", true); r = mongoc_collection_validate (collection, &opts, &reply, &error); assert (r); assert (bson_iter_init_find (&iter, &reply, "ns")); assert (bson_iter_init_find (&iter, &reply, "valid")); bson_destroy (&reply); bson_reinit (&opts); BSON_APPEND_UTF8 (&opts, "full", "bad_value"); r = mongoc_collection_validate (collection, &opts, &reply, &error); assert (!r); assert (error.domain == MONGOC_ERROR_BSON); assert (error.code == MONGOC_ERROR_BSON_INVALID); r = mongoc_collection_drop (collection, &error); assert (r); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&doc); bson_destroy (&opts); }
/** * mongoc_read_concern_freeze: * @read_concern: A mongoc_read_concern_t. * * This is an internal function. * * Encodes the read concern into a bson_t, which may then be returned by * mongoc_read_concern_get_bson(). */ static void _mongoc_read_concern_freeze (mongoc_read_concern_t *read_concern) { bson_t *compiled; BSON_ASSERT (read_concern); compiled = &read_concern->compiled; read_concern->frozen = true; bson_reinit (compiled); if (read_concern->level) { BSON_APPEND_UTF8 (compiled, "level", read_concern->level); } }
static void _test_bson_json_read_compare (const char *json, int size, ...) { bson_error_t error = { 0 }; bson_json_reader_t *reader; va_list ap; int r; bson_t *compare; bson_t bson = BSON_INITIALIZER; reader = bson_json_data_reader_new ((size == 1), size); bson_json_data_reader_ingest(reader, (uint8_t *)json, strlen(json)); va_start (ap, size); while ((r = bson_json_reader_read (reader, &bson, &error))) { if (r == -1) { fprintf (stderr, "%s\n", error.message); abort (); } compare = va_arg (ap, bson_t *); assert (compare); bson_eq_bson (&bson, compare); bson_destroy (compare); bson_reinit (&bson); } va_end (ap); bson_json_reader_destroy (reader); bson_destroy (&bson); }
bool mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error) { bson_t sel = BSON_INITIALIZER; bool ret = false; bson_return_val_if_fail (file, false); BSON_APPEND_VALUE (&sel, "_id", &file->files_id); if (!mongoc_collection_remove (file->gridfs->files, MONGOC_REMOVE_SINGLE_REMOVE, &sel, NULL, error)) { goto cleanup; } bson_reinit (&sel); BSON_APPEND_VALUE (&sel, "files_id", &file->files_id); if (!mongoc_collection_remove (file->gridfs->chunks, MONGOC_REMOVE_NONE, &sel, NULL, error)) { goto cleanup; } ret = true; cleanup: bson_destroy (&sel); return ret; }
static void test_func_inherits_opts (void *ctx) { opt_inheritance_test_t *test = (opt_inheritance_test_t *) ctx; /* for example, test mongoc_collection_find_with_opts with no read pref, * with a read pref set on the collection (OPT_SOURCE_COLL), with an explicit * read pref (OPT_SOURCE_FUNC), or with one read pref on the collection and * a different one passed explicitly */ opt_source_t source_matrix[] = {OPT_SOURCE_NONE, test->opt_source, OPT_SOURCE_FUNC, test->opt_source | OPT_SOURCE_FUNC}; size_t i; func_ctx_t func_ctx; mock_rs_t *rs; mongoc_client_t *client; mongoc_database_t *db; mongoc_collection_t *collection; bson_t opts = BSON_INITIALIZER; mongoc_read_prefs_t *func_prefs = NULL; future_t *future; request_t *request; bson_t cmd = BSON_INITIALIZER; bool expect_secondary; bson_error_t error; /* one primary, one secondary */ rs = mock_rs_with_autoismaster (WIRE_VERSION_OP_MSG, true, 1, 0); /* we use read pref tags like "collection": "yes" to verify where the * pref was inherited from; ensure all secondaries match all tags */ mock_rs_tag_secondary (rs, 0, tmp_bson ("{'client': 'yes'," " 'database': 'yes'," " 'collection': 'yes'," " 'function': 'yes'}")); mock_rs_run (rs); /* iterate over all combinations of options sources: e.g., an option set on * collection and not function, on function not collection, both, neither */ for (i = 0; i < sizeof (source_matrix) / (sizeof (opt_source_t)); i++) { expect_secondary = false; func_prefs = NULL; bson_reinit (&cmd); bson_reinit (&opts); client = mongoc_client_new_from_uri (mock_rs_get_uri (rs)); if (source_matrix[i] & OPT_SOURCE_CLIENT) { set_client_opt (client, test->opt_type); } db = mongoc_client_get_database (client, "database"); if (source_matrix[i] & OPT_SOURCE_DB) { set_database_opt (db, test->opt_type); } collection = mongoc_database_get_collection (db, "collection"); if (source_matrix[i] & OPT_SOURCE_COLL) { set_collection_opt (collection, test->opt_type); } if (source_matrix[i] & OPT_SOURCE_FUNC) { set_func_opt (&opts, &func_prefs, test->opt_type); } func_ctx_init ( &func_ctx, test, client, db, collection, func_prefs, &opts); /* func_with_opts creates expected "cmd", like {insert: 'collection'} */ future = test->func_with_opts (&func_ctx, &cmd); if (source_matrix[i] != OPT_SOURCE_NONE) { add_expected_opt (source_matrix[i], test->opt_type, &cmd); if (test->opt_type == OPT_READ_PREFS) { expect_secondary = true; } } /* write commands send two OP_MSG sections */ if (test->n_sections == 2) { request = mock_rs_receives_msg (rs, 0, &cmd, tmp_bson ("{}")); } else { request = mock_rs_receives_msg (rs, 0, &cmd); } if (expect_secondary) { BSON_ASSERT (mock_rs_request_is_to_secondary (rs, request)); } else { BSON_ASSERT (mock_rs_request_is_to_primary (rs, request)); } if (func_ctx.cursor) { mock_server_replies_simple (request, "{'ok': 1," " 'cursor': {" " 'id': 0," " 'ns': 'db.collection'," " 'firstBatch': []}}"); BSON_ASSERT (!future_get_bool (future)); future_destroy (future); ASSERT_OR_PRINT (!mongoc_cursor_error (func_ctx.cursor, &error), error); } else { mock_server_replies_simple (request, "{'ok': 1}"); cleanup_future (future); } request_destroy (request); mongoc_read_prefs_destroy (func_prefs); func_ctx_cleanup (&func_ctx); mongoc_collection_destroy (collection); mongoc_database_destroy (db); mongoc_client_destroy (client); } bson_destroy (&cmd); bson_destroy (&opts); mock_rs_destroy (rs); }
static bool txn_commit (mongoc_client_session_t *session, bool explicitly_retrying, bson_t *reply, bson_error_t *error) { bson_t cmd = BSON_INITIALIZER; bson_t opts = BSON_INITIALIZER; bson_error_t err_local; bson_error_t *err_ptr = error ? error : &err_local; bson_t reply_local = BSON_INITIALIZER; mongoc_write_err_type_t error_type; bool r = false; bool retrying_after_error = false; mongoc_write_concern_t *retry_wc = NULL; _mongoc_bson_init_if_set (reply); BSON_APPEND_INT32 (&cmd, "commitTransaction", 1); retry: if (!mongoc_client_session_append (session, &opts, err_ptr)) { GOTO (done); } /* Transactions Spec: "When commitTransaction is retried, either by the * driver's internal retry-once logic or explicitly by the user calling * commitTransaction again, drivers MUST apply w:majority to the write * concern of the commitTransaction command." */ if (!retry_wc && (retrying_after_error || explicitly_retrying)) { retry_wc = create_commit_retry_wc (session->txn.opts.write_concern ? session->txn.opts.write_concern : session->client->write_concern); } if (retry_wc || session->txn.opts.write_concern) { if (!mongoc_write_concern_append ( retry_wc ? retry_wc : session->txn.opts.write_concern, &opts)) { bson_set_error (err_ptr, MONGOC_ERROR_TRANSACTION, MONGOC_ERROR_TRANSACTION_INVALID_STATE, "Invalid transaction write concern"); GOTO (done); } } /* will be reinitialized by mongoc_client_write_command_with_opts */ bson_destroy (&reply_local); r = mongoc_client_write_command_with_opts ( session->client, "admin", &cmd, &opts, &reply_local, err_ptr); /* Transactions Spec: "Drivers MUST retry the commitTransaction command once * after it fails with a retryable error", same for abort */ error_type = _mongoc_write_error_get_type (r, err_ptr, &reply_local); if (!retrying_after_error && error_type == MONGOC_WRITE_ERR_RETRY) { retrying_after_error = true; /* retry after error only once */ bson_reinit (&opts); GOTO (retry); } /* Transactions Spec: "add the UnknownTransactionCommitResult error label * when commitTransaction fails with a network error, server selection * error, or write concern failed / timeout." */ if (reply) { if ((!r && err_ptr->domain == MONGOC_ERROR_SERVER_SELECTION) || error_type == MONGOC_WRITE_ERR_RETRY || error_type == MONGOC_WRITE_ERR_WRITE_CONCERN) { bson_copy_to_excluding_noinit ( &reply_local, reply, "errorLabels", NULL); copy_labels_plus_unknown_commit_result (&reply_local, reply); } else { /* maintain invariants: reply & reply_local are valid until the end */ bson_destroy (reply); bson_steal (reply, &reply_local); bson_init (&reply_local); } } done: bson_destroy (&reply_local); bson_destroy (&cmd); bson_destroy (&opts); if (retry_wc) { mongoc_write_concern_destroy (retry_wc); } return r; }
static void _mongoc_write_opquery (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { mongoc_cmd_parts_t parts; bson_iter_t iter; const char *key; uint32_t len = 0; bson_t ar; bson_t cmd; bson_t reply; char str[16]; bool has_more; bool ret = false; uint32_t i; int32_t max_bson_obj_size; int32_t max_write_batch_size; uint32_t overhead; uint32_t key_len; int data_offset = 0; bson_reader_t *reader; const bson_t *bson; bool eof; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); bson_init (&cmd); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); max_write_batch_size = mongoc_server_stream_max_write_batch_size (server_stream); again: has_more = false; i = 0; _mongoc_write_command_init (&cmd, command, collection); /* 1 byte to specify array type, 1 byte for field name's null terminator */ overhead = cmd.len + 2 + gCommandFieldLens[command->type]; reader = bson_reader_new_from_data (command->payload.data + data_offset, command->payload.len - data_offset); bson_append_array_begin (&cmd, gCommandFields[command->type], gCommandFieldLens[command->type], &ar); while ((bson = bson_reader_read (reader, &eof))) { key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str); len = bson->len; /* 1 byte to specify document type, 1 byte for key's null terminator */ if (_mongoc_write_command_will_overflow (overhead, key_len + len + 2 + ar.len, i, max_bson_obj_size, max_write_batch_size)) { has_more = true; break; } BSON_APPEND_DOCUMENT (&ar, key, bson); data_offset += len; i++; } bson_append_array_end (&cmd, &ar); if (!i) { _mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size); result->failed = true; result->must_stop = true; ret = false; if (bson) { data_offset += len; } } else { mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd); parts.is_write_command = true; parts.assembled.operation_id = command->operation_id; if (!mongoc_cmd_parts_set_write_concern ( &parts, write_concern, server_stream->sd->max_wire_version, error)) { bson_reader_destroy (reader); bson_destroy (&cmd); mongoc_cmd_parts_cleanup (&parts); EXIT; } BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts)); if (!mongoc_cmd_parts_append_opts ( &parts, &iter, server_stream->sd->max_wire_version, error)) { bson_reader_destroy (reader); bson_destroy (&cmd); mongoc_cmd_parts_cleanup (&parts); EXIT; } ret = mongoc_cmd_parts_assemble (&parts, server_stream, error); if (ret) { ret = mongoc_cluster_run_command_monitored ( &client->cluster, &parts.assembled, &reply, error); } else { /* assembling failed */ result->must_stop = true; bson_init (&reply); } if (!ret) { result->failed = true; if (bson_empty (&reply)) { /* assembling failed, or a network error running the command */ result->must_stop = true; } } _mongoc_write_result_merge (result, command, &reply, offset); offset += i; bson_destroy (&reply); mongoc_cmd_parts_cleanup (&parts); } bson_reader_destroy (reader); if (has_more && (ret || !command->flags.ordered) && !result->must_stop) { bson_reinit (&cmd); GOTO (again); } bson_destroy (&cmd); EXIT; }
int64_t load_table (mongoc_database_t *db, const char *table_name, bson_t *bson_schema) { int64_t ret = true; column_map_t *column_map, *column_map_p; int column_map_size, i; double start_time, end_time, delta_time; FILE *fp; mongoc_collection_t *collection; mongoc_bulk_operation_t *bulk; size_t n_docs = 0; char *token; bson_t bson, reply; int64_t count = 0; bson_error_t error; fprintf (stderr, "load_table table_name: \"%s\"\n", table_name); get_column_map (bson_schema, table_name, &column_map, &column_map_size) || DIE; snprintf (mbdump_file, MAXPATHLEN, "%s/%s", mbdump_dir, table_name); /* fprintf (stderr, "mbdump_file: \"%s\"\n", mbdump_file); */ start_time = dtimeofday (); fp = fopen (mbdump_file, "r"); if (!fp) DIE; collection = mongoc_database_get_collection (db, table_name); bulk = mongoc_collection_create_bulk_operation (collection, true, NULL); bson_init (&bson); while (ret && fgets (buf, BUFSIZ, fp)) { /* fputs (buf, stdout); */ chomp (buf); for (i = 0, column_map_p = column_map, token = strtok_single (buf, "\t"); i < column_map_size; i++, column_map_p++, token = strtok_single (NULL, "\t")) { bool ret; /* fprintf (stderr, "%s: \"%s\" [%d/%d](%s)\n", column_map_p->column_name, token, i, column_map_size, column_map_p->data_type); fflush (stdout); */ ret = (*column_map_p->bson_append_from_s) (&bson, column_map_p->column_name, token); ret || fprintf (stderr, "WARNING: column_map_p->bson_append_from_s failed column %s: \"%s\" [%d/%d](%s)\n", column_map_p->column_name, token, i, column_map_size, column_map_p->data_type); } /* bson_printf ("bson: %s\n", &bson); */ mongoc_bulk_operation_insert (bulk, &bson); bson_reinit (&bson); if (++n_docs == BULK_OPS_SIZE) { ret = mongoc_bulk_operation_execute (bulk, &reply, &error); if (ret) { count += n_docs; if (count % PROGRESS_SIZE == 0) { fputc('.', stdout); fflush(stdout); } } else fprintf (stderr, "mongoc_cursor_bulk_insert execute failure: %s\n", error.message); n_docs = 0; mongoc_bulk_operation_destroy (bulk); bulk = mongoc_collection_create_bulk_operation (collection, true, NULL); } } if (ret && n_docs > 0) { ret = mongoc_bulk_operation_execute (bulk, &reply, &error); if (ret) count += n_docs; else fprintf (stderr, "mongoc_cursor_bulk_insert execute failure: %s\n", error.message); } fputc('.', stdout); fputc('\n', stdout); fflush(stdout); bson_destroy (&bson); mongoc_bulk_operation_destroy (bulk); mongoc_collection_destroy (collection); fclose (fp); end_time = dtimeofday (); delta_time = end_time - start_time + 0.0000001; fprintf (stderr, "info: real: %.2f, count: %"PRId64", %"PRId64" docs/sec\n", delta_time, count, (int64_t)round (count/delta_time)); fflush (stderr); free (column_map); return ret ? count : -1; }
bool mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson) { bson_iter_t iter; bool ret = false; BSON_ASSERT (stream); BSON_ASSERT (bson); if (stream->err.code != 0) { goto end; } BSON_ASSERT (stream->cursor); if (!mongoc_cursor_next (stream->cursor, bson)) { const bson_t *err_doc; bson_error_t err; bool resumable = false; if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) { /* no error occurred, just no documents left. */ goto end; } resumable = _is_resumable_error (err_doc); if (resumable) { /* recreate the cursor. */ mongoc_cursor_destroy (stream->cursor); stream->cursor = NULL; if (!_make_cursor (stream)) { goto end; } if (!mongoc_cursor_next (stream->cursor, bson)) { resumable = !mongoc_cursor_error_document (stream->cursor, &err, &err_doc); if (resumable) { /* empty batch. */ goto end; } } } if (!resumable) { stream->err = err; bson_destroy (&stream->err_doc); bson_copy_to (err_doc, &stream->err_doc); goto end; } } /* we have received documents, either from the first call to next or after a * resume. */ if (!bson_iter_init_find (&iter, *bson, "_id")) { bson_set_error (&stream->err, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN, "Cannot provide resume functionality when the resume " "token is missing"); goto end; } /* copy the resume token. */ bson_reinit (&stream->resume_token); BSON_APPEND_VALUE ( &stream->resume_token, "resumeAfter", bson_iter_value (&iter)); /* clear out the operation time, since we no longer need it to resume. */ _mongoc_timestamp_clear (&stream->operation_time); ret = true; end: /* Driver Sessions Spec: "When an implicit session is associated with a * cursor for use with getMore operations, the session MUST be returned to * the pool immediately following a getMore operation that indicates that the * cursor has been exhausted." */ if (stream->implicit_session) { /* if creating the change stream cursor errored, it may be null. */ if (!stream->cursor || stream->cursor->cursor_id == 0) { mongoc_client_session_destroy (stream->implicit_session); stream->implicit_session = NULL; } } return ret; }