Skip to content

CDRIVER-4363 add client bulk write #1590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6535664
fix comment in `_mongoc_write_opmsg`
kevinAlbs Apr 30, 2024
460bd8d
quote key in match error
kevinAlbs Apr 30, 2024
cc19e7a
propagate error for numeric mismatch
kevinAlbs Apr 30, 2024
e1298a0
add `ASSERT_EQUAL_BSON`
kevinAlbs Apr 30, 2024
8bbaecc
align print on match failure
kevinAlbs Apr 30, 2024
2e479db
implement client bulk write
kevinAlbs Apr 30, 2024
c8e4763
add example use
kevinAlbs Apr 30, 2024
c1dccd1
add prose tests
kevinAlbs Apr 30, 2024
43d3e65
add specification tests
kevinAlbs Apr 30, 2024
6f44f72
support string `w` URI option in test runner
kevinAlbs Apr 30, 2024
b031041
update unified test runner
kevinAlbs Apr 30, 2024
8a4cda6
remove redundant `write_errors` check
kevinAlbs May 10, 2024
59c4446
remove `mongoc_opt_bool_t`
kevinAlbs May 10, 2024
fd788ef
add `ERROR_IF_EXECUTED` macro
kevinAlbs May 10, 2024
4717551
use `BSON_APPEND_*` macros instead of hard coded lengths
kevinAlbs May 10, 2024
86225a2
remove repeated call to `bson_iter_init_find`
kevinAlbs May 10, 2024
26ac0ff
avoid repeated calls to `_mongoc_document_is_pipeline`
kevinAlbs May 10, 2024
1c18ae5
remove `mongoc_bulkwrite_replaceoneopts_set_arrayfilters`
kevinAlbs May 11, 2024
c150e70
remove `mongoc_bulkwriteresult_acknowledged`
kevinAlbs May 11, 2024
6886add
expect non-NULL `error`
kevinAlbs May 13, 2024
d5f0c6d
remove server ID assignment
kevinAlbs May 13, 2024
fbf0678
assign server ID on retry
kevinAlbs May 13, 2024
00ceb67
test upsert with null `_id`
kevinAlbs May 13, 2024
eff456e
check for stream validity before sending command
kevinAlbs May 13, 2024
960723e
add missing assignment of server ID
kevinAlbs May 13, 2024
77b30ed
assign server ID shortly before end
kevinAlbs May 13, 2024
e5c978d
add missing `_bulkwriteexception_set_error_reply`
kevinAlbs May 13, 2024
24904ae
clarify calculation of opmsg_overhead for collection bulk write
kevinAlbs May 13, 2024
93feb70
test matching with numerics
kevinAlbs May 14, 2024
a75a4eb
add `lookup_as_int64`, and fix verbose results
kevinAlbs May 14, 2024
60ca972
remove `lookup_double`
kevinAlbs May 14, 2024
0394f43
refer to spec for prose test 11 values
kevinAlbs May 14, 2024
b4182ec
simplify `check_schema_version`
kevinAlbs May 14, 2024
35f2bfc
split handling top-level reply fields into `_bulkwritereturn_apply_re…
kevinAlbs May 14, 2024
3abda24
split handling top-level reply fields into `_bulkwritereturn_apply_re…
kevinAlbs May 14, 2024
65a6869
relocate comment
kevinAlbs May 14, 2024
b5cb200
add `BSON_OPTIONAL_PARAM` macro
kevinAlbs May 16, 2024
f1980a5
replace `BSON_ASSERT (X || true)` with `BSON_OPTIONAL_PARAM (X)`
kevinAlbs May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/common/common-macros-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@
#define MONGOC_DEBUG_ASSERT(statement) ((void) 0)
#endif

// `MC_ENABLE_CONVERSION_WARNING_BEGIN` enables -Wconversion to check for potentially unsafe integer conversions.
// The `bson_in_range_*` functions can help address these warnings by ensuring a cast is within bounds.
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) // gcc 4.6 added support for "diagnostic push".
#define MC_ENABLE_CONVERSION_WARNING_BEGIN \
_Pragma ("GCC diagnostic push") _Pragma ("GCC diagnostic warning \"-Wconversion\"")
#define MC_ENABLE_CONVERSION_WARNING_END _Pragma ("GCC diagnostic pop")
#elif defined(__clang__)
#define MC_ENABLE_CONVERSION_WARNING_BEGIN \
_Pragma ("clang diagnostic push") _Pragma ("clang diagnostic warning \"-Wconversion\"")
#define MC_ENABLE_CONVERSION_WARNING_END _Pragma ("clang diagnostic pop")
#else
#define MC_ENABLE_CONVERSION_WARNING_BEGIN
#define MC_ENABLE_CONVERSION_WARNING_END
#endif

#endif
4 changes: 2 additions & 2 deletions src/common/common-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void
{
BSON_ASSERT_PARAM (thread);
BSON_ASSERT_PARAM (func);
BSON_ASSERT (arg || true); // optional.
BSON_OPTIONAL_PARAM (arg); // optional.
return pthread_create (thread, NULL, func, arg);
}
int
Expand All @@ -47,7 +47,7 @@ mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void
{
BSON_ASSERT_PARAM (thread);
BSON_ASSERT_PARAM (func);
BSON_ASSERT (arg || true); // optional.
BSON_OPTIONAL_PARAM (arg); // optional.

*thread = (HANDLE) _beginthreadex (NULL, 0, func, arg, 0, NULL);
if (0 == *thread) {
Expand Down
4 changes: 4 additions & 0 deletions src/libbson/src/bson/bson-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@
} \
} while (0)

// `BSON_OPTIONAL_PARAM` is a documentation-only macro to document X may be NULL.
// Useful in combination with `BSON_ASSERT_PARAM` to document and assert pointer parameters.
#define BSON_OPTIONAL_PARAM(param) (void) 0

/* obsolete macros, preserved for compatibility */
#define BSON_STATIC_ASSERT(s) BSON_STATIC_ASSERT_ (s, __LINE__)
#define BSON_STATIC_ASSERT_JOIN(a, b) BSON_STATIC_ASSERT_JOIN2 (a, b)
Expand Down
5 changes: 5 additions & 0 deletions src/libmongoc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ set (SOURCES ${SOURCES}
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl-bio.c
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-openssl.c
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ocsp-cache.c
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.c
)

set (HEADERS
Expand All @@ -666,6 +667,7 @@ set (HEADERS
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-apm.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulk-operation.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-change-stream.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-pool.h
Expand Down Expand Up @@ -713,6 +715,7 @@ set (HEADERS
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ssl.h
${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.h
)

set (HEADERS_FORWARDING
Expand Down Expand Up @@ -1012,6 +1015,7 @@ set (test-libmongoc-sources
${PROJECT_SOURCE_DIR}/tests/test-mongoc-background-monitoring.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-buffer.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-bulk.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-bulkwrite.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-change-stream.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-pool.c
${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-session.c
Expand Down Expand Up @@ -1226,6 +1230,7 @@ if (ENABLE_EXAMPLES AND ENABLE_SHARED)
mongoc_add_example (mongoc-ping ${PROJECT_SOURCE_DIR}/examples/mongoc-ping.c)
mongoc_add_example (mongoc-tail ${PROJECT_SOURCE_DIR}/examples/mongoc-tail.c)
mongoc_add_example (example-collection-command ${PROJECT_SOURCE_DIR}/examples/example-collection-command.c)
mongoc_add_example (example-bulkwrite ${PROJECT_SOURCE_DIR}/examples/example-bulkwrite.c)

# examples/aggregation/
mongoc_add_example (aggregation1 ${PROJECT_SOURCE_DIR}/examples/aggregation/aggregation1.c)
Expand Down
87 changes: 87 additions & 0 deletions src/libmongoc/examples/example-bulkwrite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// example-bulkwrite shows use of `mongoc_client_bulkwrite`.

#include <mongoc/mongoc.h>

#define HANDLE_ERROR(...) \
if (1) { \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
goto fail; \
} else \
(void) 0

int
main (int argc, char *argv[])
{
bool ok = false;

mongoc_init ();

bson_error_t error;
mongoc_client_t *client = mongoc_client_new ("mongodb://localhost:27017");
mongoc_bulkwriteopts_t *bwo = mongoc_bulkwriteopts_new ();
mongoc_bulkwriteopts_set_verboseresults (bwo, true);
mongoc_bulkwrite_t *bw = mongoc_client_bulkwrite_new (client);

// Insert a document to `db.coll1`
{
bson_t *doc = BCON_NEW ("foo", "bar");
if (!mongoc_bulkwrite_append_insertone (bw, "db.coll1", doc, NULL, &error)) {
HANDLE_ERROR ("Error appending insert one: %s", error.message);
}
bson_destroy (doc);
}
// Insert a document to `db.coll2`
{
bson_t *doc = BCON_NEW ("foo", "baz");
if (!mongoc_bulkwrite_append_insertone (bw, "db.coll2", doc, NULL, &error)) {
HANDLE_ERROR ("Error appending insert one: %s", error.message);
}
bson_destroy (doc);
}

mongoc_bulkwritereturn_t bwr = mongoc_bulkwrite_execute (bw, bwo);

// Print results.
{
BSON_ASSERT (bwr.res); // Has results. NULL only returned for unacknowledged writes.
printf ("Insert count : %" PRId64 "\n", mongoc_bulkwriteresult_insertedcount (bwr.res));
const bson_t *ir = mongoc_bulkwriteresult_insertresults (bwr.res);
BSON_ASSERT (ir); // Has verbose results. NULL only returned if verbose results not requested.
char *ir_str = bson_as_relaxed_extended_json (ir, NULL);
printf ("Insert results : %s\n", ir_str);
bson_free (ir_str);
}

// Print all error information. To observe: try setting the `_id` fields to cause a duplicate key error.
if (bwr.exc) {
const char *msg = "(none)";
if (mongoc_bulkwriteexception_error (bwr.exc, &error)) {
msg = error.message;
}
const bson_t *we = mongoc_bulkwriteexception_writeerrors (bwr.exc);
char *we_str = bson_as_relaxed_extended_json (we, NULL);
const bson_t *wce = mongoc_bulkwriteexception_writeconcernerrors (bwr.exc);
char *wce_str = bson_as_relaxed_extended_json (wce, NULL);
const bson_t *er = mongoc_bulkwriteexception_errorreply (bwr.exc);
char *er_str = bson_as_relaxed_extended_json (er, NULL);
printf ("Top-level error : %s\n", msg);
printf ("Write errors : %s\n", we_str);
printf ("Write concern errors : %s\n", wce_str);
printf ("Error reply : %s\n", er_str);
bson_free (er_str);
bson_free (wce_str);
bson_free (we_str);
}

mongoc_bulkwriteresult_destroy (bwr.res);
mongoc_bulkwriteexception_destroy (bwr.exc);
mongoc_bulkwrite_destroy (bw);

ok = true;
fail:
mongoc_client_destroy (client);
mongoc_bulkwriteopts_destroy (bwo);
mongoc_cleanup ();
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
2 changes: 1 addition & 1 deletion src/libmongoc/src/mongoc/mcd-nsinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ mcd_nsinfo_append (mcd_nsinfo_t *self, const char *ns, bson_error_t *error)
{
BSON_ASSERT_PARAM (self);
BSON_ASSERT_PARAM (ns);
BSON_ASSERT (error || true);
BSON_OPTIONAL_PARAM (error);

const int32_t ns_index = self->count;
if (self->count == INT32_MAX) {
Expand Down
6 changes: 3 additions & 3 deletions src/libmongoc/src/mongoc/mcd-rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ _consume_bson_objects (const uint8_t **ptr, size_t *remaining_bytes, int32_t *nu
{
BSON_ASSERT_PARAM (ptr);
BSON_ASSERT_PARAM (remaining_bytes);
BSON_ASSERT (num_parsed || true);
BSON_OPTIONAL_PARAM (num_parsed);

int32_t count = 0;

Expand Down Expand Up @@ -814,7 +814,7 @@ mcd_rpc_message *
mcd_rpc_message_from_data (const void *data, size_t length, const void **data_end)
{
BSON_ASSERT_PARAM (data);
BSON_ASSERT (data_end || true);
BSON_OPTIONAL_PARAM (data_end);

mcd_rpc_message *rpc = bson_malloc (sizeof (mcd_rpc_message));
mcd_rpc_message *ret = NULL;
Expand All @@ -838,7 +838,7 @@ mcd_rpc_message_from_data_in_place (mcd_rpc_message *rpc, const void *data, size
{
ASSERT_MCD_RPC_ACCESSOR_PRECONDITIONS;
BSON_ASSERT_PARAM (data);
BSON_ASSERT (data_end || true);
BSON_OPTIONAL_PARAM (data_end);

bool ret = false;

Expand Down
Loading