Skip to content

Commit 9030117

Browse files
committed
CDRIVER-5816 allow constructing mongoc_bulkwrite_t without a client
1 parent 8eba3f6 commit 9030117

File tree

6 files changed

+129
-2
lines changed

6 files changed

+129
-2
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
:man_page: mongoc_bulkwrite_new
2+
3+
mongoc_bulkwrite_new()
4+
======================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
mongoc_bulkwrite_t *
12+
mongoc_bulkwrite_new (void);
13+
14+
Description
15+
-----------
16+
17+
Returns a new :symbol:`mongoc_bulkwrite_t`. Free with :symbol:`mongoc_bulkwrite_destroy()`.
18+
19+
A client must be assigned with :symbol:`mongoc_bulkwrite_set_client()` prior to execution.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
:man_page: mongoc_bulkwrite_set_client
2+
3+
mongoc_bulkwrite_set_client()
4+
=============================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_bulkwrite_set_client (mongoc_bulkwrite_t *self, mongoc_client_t *client);
13+
14+
Description
15+
-----------
16+
17+
Sets the client that will be used to execute the :symbol:`mongoc_bulkwrite_t`.

src/libmongoc/doc/mongoc_bulkwrite_t.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ to execute the operation.
5050
mongoc_bulkwrite_deletemanyopts_t
5151
mongoc_bulkwrite_append_deletemany
5252
mongoc_bulkwritereturn_t
53+
mongoc_bulkwrite_new
54+
mongoc_bulkwrite_set_client
5355
mongoc_bulkwrite_set_session
5456
mongoc_bulkwrite_execute
5557
mongoc_bulkwrite_destroy

src/libmongoc/src/mongoc/mongoc-bulkwrite.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,18 @@ mongoc_bulkwrite_t *
169169
mongoc_client_bulkwrite_new (mongoc_client_t *self)
170170
{
171171
BSON_ASSERT_PARAM (self);
172-
mongoc_bulkwrite_t *bw = bson_malloc0 (sizeof (mongoc_bulkwrite_t));
172+
mongoc_bulkwrite_t *bw = mongoc_bulkwrite_new ();
173173
bw->client = self;
174+
bw->operation_id = ++self->cluster.operation_id;
175+
return bw;
176+
}
177+
178+
mongoc_bulkwrite_t *
179+
mongoc_bulkwrite_new (void)
180+
{
181+
mongoc_bulkwrite_t *bw = bson_malloc0 (sizeof (mongoc_bulkwrite_t));
174182
_mongoc_buffer_init (&bw->ops, NULL, 0, NULL, NULL);
175183
_mongoc_array_init (&bw->arrayof_modeldata, sizeof (modeldata_t));
176-
bw->operation_id = ++self->cluster.operation_id;
177184
return bw;
178185
}
179186

@@ -1438,6 +1445,26 @@ _bulkwritereturn_apply_result (mongoc_bulkwritereturn_t *self,
14381445
return true;
14391446
}
14401447

1448+
MONGOC_EXPORT (void)
1449+
mongoc_bulkwrite_set_client (mongoc_bulkwrite_t *self, mongoc_client_t *client)
1450+
{
1451+
BSON_ASSERT_PARAM (self);
1452+
BSON_ASSERT_PARAM (client);
1453+
1454+
if (self->session) {
1455+
BSON_ASSERT (self->session->client == client);
1456+
}
1457+
1458+
/* NOP if the client is not changing; otherwise, assign it and increment and
1459+
* fetch its operation_id. */
1460+
if (self->client == client) {
1461+
return;
1462+
}
1463+
1464+
self->client = client;
1465+
self->operation_id = ++client->cluster.operation_id;
1466+
}
1467+
14411468
BSON_EXPORT (void)
14421469
mongoc_bulkwrite_set_session (mongoc_bulkwrite_t *self, mongoc_client_session_t *session)
14431470
{
@@ -1471,6 +1498,15 @@ mongoc_bulkwrite_execute (mongoc_bulkwrite_t *self, const mongoc_bulkwriteopts_t
14711498
ret.res = _bulkwriteresult_new ();
14721499
ret.exc = _bulkwriteexception_new ();
14731500

1501+
if (!self->client) {
1502+
bson_set_error (&error,
1503+
MONGOC_ERROR_COMMAND,
1504+
MONGOC_ERROR_COMMAND_INVALID_ARG,
1505+
"bulk write requires a client and one has not been set");
1506+
_bulkwriteexception_set_error (ret.exc, &error);
1507+
goto fail;
1508+
}
1509+
14741510
if (self->executed) {
14751511
bson_set_error (&error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "bulk write already executed");
14761512
_bulkwriteexception_set_error (ret.exc, &error);

src/libmongoc/src/mongoc/mongoc-bulkwrite.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ mongoc_bulkwriteexception_destroy (mongoc_bulkwriteexception_t *self);
127127
typedef struct _mongoc_bulkwrite_t mongoc_bulkwrite_t;
128128
MONGOC_EXPORT (mongoc_bulkwrite_t *)
129129
mongoc_client_bulkwrite_new (mongoc_client_t *self);
130+
130131
typedef struct _mongoc_bulkwrite_insertoneopts_t mongoc_bulkwrite_insertoneopts_t;
131132
MONGOC_EXPORT (mongoc_bulkwrite_insertoneopts_t *)
132133
mongoc_bulkwrite_insertoneopts_new (void);
@@ -239,6 +240,13 @@ typedef struct {
239240
mongoc_bulkwriteexception_t *exc; // NULL if no error.
240241
} mongoc_bulkwritereturn_t;
241242

243+
// `mongoc_bulkwrite_new` and `mongoc_bulkwrite_set_client` may be used by
244+
// language bindings that want to assemble a `mongoc_bulkwrite_t` and defer
245+
// `mongoc_client_t` assignment to execution time.
246+
MONGOC_EXPORT (mongoc_bulkwrite_t *)
247+
mongoc_bulkwrite_new (void);
248+
MONGOC_EXPORT (void)
249+
mongoc_bulkwrite_set_client (mongoc_bulkwrite_t *self, mongoc_client_t *client);
242250
// `mongoc_bulkwrite_set_session` sets an optional explicit session.
243251
// `*session` may be modified when `mongoc_bulkwrite_execute` is called.
244252
MONGOC_EXPORT (void)

src/libmongoc/tests/test-mongoc-bulkwrite.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,43 @@ test_bulkwrite_many_namespaces (void *ctx)
591591
mongoc_client_destroy (client);
592592
}
593593

594+
static void
595+
test_bulkwrite_execute_requires_client (void *ctx)
596+
{
597+
BSON_UNUSED (ctx);
598+
bool ok;
599+
bson_error_t error;
600+
601+
mongoc_client_t *client = test_framework_new_default_client ();
602+
mongoc_bulkwrite_t *bw = mongoc_bulkwrite_new ();
603+
ok = mongoc_bulkwrite_append_insertone (bw, "db.coll", tmp_bson ("{}"), NULL, &error);
604+
ASSERT_OR_PRINT (ok, error);
605+
606+
// Attempt execution without assigning a client
607+
{
608+
mongoc_bulkwritereturn_t bwr = mongoc_bulkwrite_execute (bw, NULL);
609+
ASSERT (bwr.exc);
610+
ASSERT (mongoc_bulkwriteexception_error (bwr.exc, &error));
611+
ASSERT_ERROR_CONTAINS (error,
612+
MONGOC_ERROR_COMMAND,
613+
MONGOC_ERROR_COMMAND_INVALID_ARG,
614+
"bulk write requires a client and one has not been set");
615+
mongoc_bulkwriteexception_destroy (bwr.exc);
616+
mongoc_bulkwriteresult_destroy (bwr.res);
617+
}
618+
619+
// Assign a client and execute successfully
620+
{
621+
mongoc_bulkwrite_set_client (bw, client);
622+
mongoc_bulkwritereturn_t bwr = mongoc_bulkwrite_execute (bw, NULL);
623+
ASSERT_NO_BULKWRITEEXCEPTION (bwr);
624+
mongoc_bulkwriteresult_destroy (bwr.res);
625+
mongoc_bulkwriteexception_destroy (bwr.exc);
626+
}
627+
628+
mongoc_bulkwrite_destroy (bw);
629+
mongoc_client_destroy (client);
630+
}
594631

595632
void
596633
test_bulkwrite_install (TestSuite *suite)
@@ -677,4 +714,12 @@ test_bulkwrite_install (TestSuite *suite)
677714
test_framework_skip_if_max_wire_version_less_than_25, // require server 8.0
678715
test_framework_skip_if_mongos // Creating 100k collections is very slow (~5 minutes) on mongos.
679716
);
717+
718+
TestSuite_AddFull (suite,
719+
"/bulkwrite/execute_requires_client",
720+
test_bulkwrite_execute_requires_client,
721+
NULL /* dtor */,
722+
NULL /* ctx */,
723+
test_framework_skip_if_max_wire_version_less_than_25 // require server 8.0
724+
);
680725
}

0 commit comments

Comments
 (0)