Skip to content

Commit f5ade59

Browse files
author
Christian Hergert
committed
bulk: add mongoc_bulk_operation_new()
This is useful for situations where you want to create bulk operations and replay them a number of times. Fixes CDRIVER-391.
1 parent daadcbb commit f5ade59

File tree

7 files changed

+189
-17
lines changed

7 files changed

+189
-17
lines changed

build/cmake/libmongoc-ssl.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ mongoc_bulk_operation_delete_one
44
mongoc_bulk_operation_destroy
55
mongoc_bulk_operation_execute
66
mongoc_bulk_operation_insert
7+
mongoc_bulk_operation_new
78
mongoc_bulk_operation_remove
89
mongoc_bulk_operation_remove_one
910
mongoc_bulk_operation_replace_one
11+
mongoc_bulk_operation_set_client
12+
mongoc_bulk_operation_set_collection
13+
mongoc_bulk_operation_set_database
14+
mongoc_bulk_operation_set_hint
1015
mongoc_bulk_operation_set_write_concern
1116
mongoc_bulk_operation_update
1217
mongoc_bulk_operation_update_one

build/cmake/libmongoc.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ mongoc_bulk_operation_delete_one
44
mongoc_bulk_operation_destroy
55
mongoc_bulk_operation_execute
66
mongoc_bulk_operation_insert
7+
mongoc_bulk_operation_new
78
mongoc_bulk_operation_remove
89
mongoc_bulk_operation_remove_one
910
mongoc_bulk_operation_replace_one
11+
mongoc_bulk_operation_set_client
12+
mongoc_bulk_operation_set_collection
13+
mongoc_bulk_operation_set_database
14+
mongoc_bulk_operation_set_hint
1015
mongoc_bulk_operation_set_write_concern
1116
mongoc_bulk_operation_update
1217
mongoc_bulk_operation_update_one

src/libmongoc.symbols

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ mongoc_bulk_operation_delete_one
33
mongoc_bulk_operation_destroy
44
mongoc_bulk_operation_execute
55
mongoc_bulk_operation_insert
6+
mongoc_bulk_operation_new
67
mongoc_bulk_operation_remove
78
mongoc_bulk_operation_remove_one
89
mongoc_bulk_operation_replace_one
10+
mongoc_bulk_operation_set_client
11+
mongoc_bulk_operation_set_collection
12+
mongoc_bulk_operation_set_database
13+
mongoc_bulk_operation_set_hint
914
mongoc_bulk_operation_set_write_concern
1015
mongoc_bulk_operation_update
1116
mongoc_bulk_operation_update_one

src/mongoc/mongoc-bulk-operation.c

Lines changed: 95 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@
4444
*/
4545

4646

47+
mongoc_bulk_operation_t *
48+
mongoc_bulk_operation_new (bool ordered)
49+
{
50+
mongoc_bulk_operation_t *bulk;
51+
52+
bulk = bson_malloc0 (sizeof *bulk);
53+
bulk->ordered = ordered;
54+
55+
_mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t));
56+
57+
return bulk;
58+
}
59+
60+
4761
mongoc_bulk_operation_t *
4862
_mongoc_bulk_operation_new (mongoc_client_t *client, /* IN */
4963
const char *database, /* IN */
@@ -57,23 +71,14 @@ _mongoc_bulk_operation_new (mongoc_client_t *client, /* IN *
5771
BSON_ASSERT (client);
5872
BSON_ASSERT (collection);
5973

60-
bulk = bson_malloc0 (sizeof *bulk);
61-
74+
bulk = mongoc_bulk_operation_new (ordered);
6275
bulk->client = client;
6376
bulk->database = bson_strdup (database);
6477
bulk->collection = bson_strdup (collection);
65-
bulk->ordered = ordered;
6678
bulk->hint = hint;
6779
bulk->write_concern = mongoc_write_concern_copy (write_concern);
6880
bulk->executed = false;
6981

70-
if (!bulk->write_concern) {
71-
bulk->write_concern = mongoc_write_concern_new ();
72-
}
73-
74-
_mongoc_write_result_init (&bulk->result);
75-
_mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t));
76-
7782
return bulk;
7883
}
7984

@@ -95,7 +100,10 @@ mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */
95100
bson_free (bulk->collection);
96101
mongoc_write_concern_destroy (bulk->write_concern);
97102
_mongoc_array_destroy (&bulk->commands);
98-
_mongoc_write_result_destroy (&bulk->result);
103+
104+
if (bulk->executed) {
105+
_mongoc_write_result_destroy (&bulk->result);
106+
}
99107

100108
bson_free (bulk);
101109
}
@@ -276,17 +284,41 @@ mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */
276284

277285
bson_return_val_if_fail (bulk, false);
278286

287+
if (!bulk->write_concern) {
288+
bulk->write_concern = mongoc_write_concern_new ();
289+
}
290+
279291
if (bulk->executed) {
292+
_mongoc_write_result_destroy (&bulk->result);
293+
}
294+
295+
_mongoc_write_result_init (&bulk->result);
296+
297+
bulk->executed = true;
298+
299+
if (!bulk->client) {
300+
bson_set_error (error,
301+
MONGOC_ERROR_COMMAND,
302+
MONGOC_ERROR_COMMAND_INVALID_ARG,
303+
"mongoc_bulk_operation_execute() requires a client "
304+
"and one has not been set.");
305+
return false;
306+
} else if (!bulk->database) {
280307
bson_set_error (error,
281308
MONGOC_ERROR_COMMAND,
282309
MONGOC_ERROR_COMMAND_INVALID_ARG,
283-
"mongoc_bulk_operation_execute() may only be called "
284-
"once for a bulk operation.");
310+
"mongoc_bulk_operation_execute() requires a database "
311+
"and one has not been set.");
312+
return false;
313+
} else if (!bulk->collection) {
314+
bson_set_error (error,
315+
MONGOC_ERROR_COMMAND,
316+
MONGOC_ERROR_COMMAND_INVALID_ARG,
317+
"mongoc_bulk_operation_execute() requires a collection "
318+
"and one has not been set.");
285319
return false;
286320
}
287321

288-
bulk->executed = true;
289-
290322
if (reply) {
291323
bson_init (reply);
292324
}
@@ -336,3 +368,51 @@ mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t *bulk,
336368
bulk->write_concern = mongoc_write_concern_new ();
337369
}
338370
}
371+
372+
373+
void
374+
mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk,
375+
const char *database)
376+
{
377+
bson_return_if_fail (bulk);
378+
379+
if (bulk->database) {
380+
bson_free (bulk->database);
381+
}
382+
383+
bulk->database = bson_strdup (database);
384+
}
385+
386+
387+
void
388+
mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk,
389+
const char *collection)
390+
{
391+
bson_return_if_fail (bulk);
392+
393+
if (bulk->collection) {
394+
bson_free (bulk->collection);
395+
}
396+
397+
bulk->collection = bson_strdup (collection);
398+
}
399+
400+
401+
void
402+
mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk,
403+
void *client)
404+
{
405+
bson_return_if_fail (bulk);
406+
407+
bulk->client = client;
408+
}
409+
410+
411+
void
412+
mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk,
413+
uint32_t hint)
414+
{
415+
bson_return_if_fail (bulk);
416+
417+
bulk->hint = hint;
418+
}

src/mongoc/mongoc-bulk-operation.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,24 @@ void mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
5858
const bson_t *selector,
5959
const bson_t *document,
6060
bool upsert);
61-
void mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t *bulk,
62-
const mongoc_write_concern_t *write_concern);
61+
62+
63+
/*
64+
* The following functions are really only useful by language bindings and
65+
* those wanting to replay a bulk operation to a number of clients or
66+
* collections.
67+
*/
68+
mongoc_bulk_operation_t *mongoc_bulk_operation_new (bool ordered);
69+
void mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t *bulk,
70+
const mongoc_write_concern_t *write_concern);
71+
void mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk,
72+
const char *database);
73+
void mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk,
74+
const char *collection);
75+
void mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk,
76+
void *client);
77+
void mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk,
78+
uint32_t hint);
6379

6480

6581
BSON_END_DECLS

src/mongoc/mongoc-collection.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <bcon.h>
1919
#include <stdio.h>
2020

21+
#include "mongoc-bulk-operation.h"
2122
#include "mongoc-bulk-operation-private.h"
2223
#include "mongoc-client-private.h"
2324
#include "mongoc-collection.h"

tests/test-bulk.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,66 @@ test_bulk_edge_case_372 (void)
422422

423423
bson_destroy (&reply);
424424

425+
mongoc_collection_drop (collection, NULL);
426+
427+
mongoc_bulk_operation_destroy (bulk);
428+
mongoc_collection_destroy (collection);
429+
mongoc_client_destroy (client);
430+
}
431+
432+
433+
static void
434+
test_bulk_new (void)
435+
{
436+
mongoc_bulk_operation_t *bulk;
437+
mongoc_collection_t *collection;
438+
mongoc_client_t *client;
439+
bson_error_t error;
440+
bson_t empty = BSON_INITIALIZER;
441+
bool r;
442+
443+
client = mongoc_client_new (gTestUri);
444+
assert (client);
445+
446+
collection = get_test_collection (client, "bulk_new");
447+
assert (collection);
448+
449+
bulk = mongoc_bulk_operation_new (true);
425450
mongoc_bulk_operation_destroy (bulk);
451+
452+
bulk = mongoc_bulk_operation_new (true);
453+
454+
r = mongoc_bulk_operation_execute (bulk, NULL, &error);
455+
assert (!r);
456+
assert (error.domain = MONGOC_ERROR_CLIENT);
457+
assert (error.code = MONGOC_ERROR_COMMAND_INVALID_ARG);
458+
459+
mongoc_bulk_operation_set_database (bulk, "test");
460+
r = mongoc_bulk_operation_execute (bulk, NULL, &error);
461+
assert (!r);
462+
assert (error.domain = MONGOC_ERROR_CLIENT);
463+
assert (error.code = MONGOC_ERROR_COMMAND_INVALID_ARG);
464+
465+
mongoc_bulk_operation_set_collection (bulk, "test");
466+
r = mongoc_bulk_operation_execute (bulk, NULL, &error);
467+
assert (!r);
468+
assert (error.domain = MONGOC_ERROR_CLIENT);
469+
assert (error.code = MONGOC_ERROR_COMMAND_INVALID_ARG);
470+
471+
mongoc_bulk_operation_set_client (bulk, client);
472+
r = mongoc_bulk_operation_execute (bulk, NULL, &error);
473+
assert (!r);
474+
assert (error.domain = MONGOC_ERROR_CLIENT);
475+
assert (error.code = MONGOC_ERROR_COMMAND_INVALID_ARG);
476+
477+
mongoc_bulk_operation_insert (bulk, &empty);
478+
r = mongoc_bulk_operation_execute (bulk, NULL, &error);
479+
assert (r);
480+
481+
mongoc_bulk_operation_destroy (bulk);
482+
483+
mongoc_collection_drop (collection, NULL);
484+
426485
mongoc_collection_destroy (collection);
427486
mongoc_client_destroy (client);
428487
}
@@ -437,6 +496,7 @@ test_bulk_install (TestSuite *suite)
437496
TestSuite_Add (suite, "/BulkOperation/update_upserted", test_update_upserted);
438497
TestSuite_Add (suite, "/BulkOperation/index_offset", test_index_offset);
439498
TestSuite_Add (suite, "/BulkOperation/CDRIVER-372", test_bulk_edge_case_372);
499+
TestSuite_Add (suite, "/BulkOperation/new", test_bulk_new);
440500

441501
atexit (cleanup_globals);
442502
}

0 commit comments

Comments
 (0)