Skip to content

Commit 2c5c9d9

Browse files
authored
CDRIVER-5640 support sort option for update+replace (#1789)
* add `sort` to `mongoc_bulk_update_one_opts_t` and `mongoc_bulk_replace_one_opts_t` Required to permit passing "sort". The collection bulk operations reject extra fields (refer CDRIVER-2665). * add `sort` to `mongoc_update_one_opts_t` and `mongoc_replace_one_opts_t` Not strictly needed. `mongoc_collection_update_one` and `mongoc_collection_replace_one` already accept the `sort` option as part of `opts`. Adding the option generates documentation. * regenerate options by running `python build/generate-opts.py` * sync tests from: mongodb/specifications@24817a5 * add `mongoc_bulkwrite_replaceoneopts_set_sort` * add `mongoc_bulkwrite_updateoneopts_set_sort` * support `sort` in unified test runner * support `sort` in `mongoc_collection_update_one` and `mongoc_collection_replace_one` * support `sort` in `mongoc_bulk_operation_update_one_with_opts` and `mongoc_bulk_operation_replace_one_with_opts`
1 parent 6a95bdb commit 2c5c9d9

22 files changed

+1452
-4
lines changed

build/generate-opts.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ def __init__(self, items, **defaults):
214214
('mongoc_update_one_opts_t', Struct([
215215
('update', {'type': 'mongoc_update_opts_t'}),
216216
array_filters_option,
217+
('sort', {'type': 'document', 'help': 'Specify a sort order when matching documents.'})
217218
], validate='_mongoc_default_update_vflags')),
218219

219220
('mongoc_update_many_opts_t', Struct([
@@ -223,6 +224,7 @@ def __init__(self, items, **defaults):
223224

224225
('mongoc_replace_one_opts_t', Struct([
225226
('update', {'type': 'mongoc_update_opts_t'}),
227+
('sort', {'type': 'document', 'help': 'Specify a sort order when matching documents.'})
226228
], validate='_mongoc_default_replace_vflags')),
227229

228230
('mongoc_bulk_opts_t', Struct([
@@ -251,6 +253,7 @@ def __init__(self, items, **defaults):
251253
('mongoc_bulk_update_one_opts_t', Struct(
252254
[
253255
('update', {'type': 'mongoc_bulk_update_opts_t'}),
256+
('sort', {'type': 'document', 'help': 'Specify a sort order when matching documents.'}),
254257
array_filters_option,
255258
],
256259
multi='false',
@@ -267,7 +270,10 @@ def __init__(self, items, **defaults):
267270
allow_extra=False)),
268271

269272
('mongoc_bulk_replace_one_opts_t', Struct(
270-
[('update', {'type': 'mongoc_bulk_update_opts_t'})],
273+
[
274+
('update', {'type': 'mongoc_bulk_update_opts_t'}),
275+
('sort', {'type': 'document', 'help': 'Specify a sort order when matching documents.'})
276+
],
271277
multi='false',
272278
validate='_mongoc_default_replace_vflags',
273279
allow_extra=False)),

src/libmongoc/doc/includes/bulk-replace-one-opts.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
* ``collation``: Configure textual comparisons. See `Setting Collation Order <setting_collation_order_>`_, and `the MongoDB Manual entry on Collation <https://www.mongodb.com/docs/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned.
1010
* ``hint``: A document or string that specifies the index to use to support the query predicate.
1111
* ``upsert``: If true, insert a document if none match ``selector``.
12+
* ``sort``: Specify a sort order when matching documents.

src/libmongoc/doc/includes/bulk-update-one-opts.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
* ``collation``: Configure textual comparisons. See `Setting Collation Order <setting_collation_order_>`_, and `the MongoDB Manual entry on Collation <https://www.mongodb.com/docs/manual/reference/collation/>`_. Collation requires MongoDB 3.2 or later, otherwise an error is returned.
1010
* ``hint``: A document or string that specifies the index to use to support the query predicate.
1111
* ``upsert``: If true, insert a document if none match ``selector``.
12+
* ``sort``: Specify a sort order when matching documents.
1213
* ``arrayFilters``: An array of filters specifying to which array elements an update should apply.

src/libmongoc/doc/includes/replace-one-opts.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
* ``hint``: A document or string that specifies the index to use to support the query predicate.
1515
* ``upsert``: When true, creates a new document if no document matches the query.
1616
* ``let``: A BSON document consisting of any number of parameter names, each followed by definitions of constants in the MQL Aggregate Expression language.
17+
* ``sort``: Specify a sort order when matching documents.

src/libmongoc/doc/includes/update-one-opts.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
* ``upsert``: When true, creates a new document if no document matches the query.
1616
* ``let``: A BSON document consisting of any number of parameter names, each followed by definitions of constants in the MQL Aggregate Expression language.
1717
* ``arrayFilters``: An array of filters specifying to which array elements an update should apply.
18+
* ``sort``: Specify a sort order when matching documents.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
:man_page: mongoc_bulkwrite_replaceoneopts_set_sort
2+
3+
mongoc_bulkwrite_replaceoneopts_set_sort()
4+
==========================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_bulkwrite_replaceoneopts_set_sort (mongoc_bulkwrite_replaceoneopts_t *self, bson_t* sort);
13+
14+
Description
15+
-----------
16+
17+
``sort`` specifies a sorting order if the query matches multiple documents.
18+
The first document matched by the sort order will be replaced.
19+
This option is only sent if the caller explicitly provides a value.

src/libmongoc/doc/mongoc_bulkwrite_replaceoneopts_t.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ Synopsis
2323
mongoc_bulkwrite_replaceoneopts_set_collation
2424
mongoc_bulkwrite_replaceoneopts_set_hint
2525
mongoc_bulkwrite_replaceoneopts_set_upsert
26+
mongoc_bulkwrite_replaceoneopts_set_sort
2627
mongoc_bulkwrite_replaceoneopts_destroy
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
:man_page: mongoc_bulkwrite_updateoneopts_set_sort
2+
3+
mongoc_bulkwrite_updateoneopts_set_sort()
4+
=========================================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
void
12+
mongoc_bulkwrite_updateoneopts_set_sort (mongoc_bulkwrite_updateoneopts_t *self, bson_t* sort);
13+
14+
Description
15+
-----------
16+
17+
``sort`` specifies a sorting order if the query matches multiple documents.
18+
The first document matched by the sort order will be updated.
19+
This option is only sent if the caller explicitly provides a value.

src/libmongoc/doc/mongoc_bulkwrite_updateoneopts_t.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ Synopsis
2424
mongoc_bulkwrite_updateoneopts_set_collation
2525
mongoc_bulkwrite_updateoneopts_set_hint
2626
mongoc_bulkwrite_updateoneopts_set_upsert
27+
mongoc_bulkwrite_updateoneopts_set_sort
2728
mongoc_bulkwrite_updateoneopts_destroy

src/libmongoc/src/mongoc/mongoc-bulk-operation.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ _mongoc_bulk_operation_update_append (mongoc_bulk_operation_t *bulk,
408408
const bson_t *document,
409409
const mongoc_bulk_update_opts_t *update_opts,
410410
const bson_t *array_filters,
411-
const bson_t *extra_opts)
411+
const bson_t *extra_opts,
412+
const bson_t *sort)
412413
{
413414
mongoc_write_command_t command = {0};
414415
mongoc_write_command_t *last;
@@ -437,6 +438,10 @@ _mongoc_bulk_operation_update_append (mongoc_bulk_operation_t *bulk,
437438
bson_append_value (&opts, "hint", 4, &update_opts->hint);
438439
}
439440

441+
if (!bson_empty0 (sort)) {
442+
bson_append_document (&opts, "sort", 4, sort);
443+
}
444+
440445
if (extra_opts) {
441446
bson_concat (&opts, extra_opts);
442447
}
@@ -483,6 +488,7 @@ _mongoc_bulk_operation_update_with_opts (mongoc_bulk_operation_t *bulk,
483488
const bson_t *array_filters,
484489
const bson_t *extra_opts,
485490
bool multi,
491+
const bson_t *sort,
486492
bson_error_t *error) /* OUT */
487493
{
488494
ENTRY;
@@ -507,7 +513,7 @@ _mongoc_bulk_operation_update_with_opts (mongoc_bulk_operation_t *bulk,
507513
RETURN (false);
508514
}
509515

510-
_mongoc_bulk_operation_update_append (bulk, selector, document, update_opts, array_filters, extra_opts);
516+
_mongoc_bulk_operation_update_append (bulk, selector, document, update_opts, array_filters, extra_opts, sort);
511517

512518
RETURN (true);
513519
}
@@ -538,6 +544,7 @@ mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
538544
&update_opts.arrayFilters,
539545
&update_opts.extra,
540546
false /* multi */,
547+
&update_opts.sort,
541548
error);
542549

543550
_mongoc_bulk_update_one_opts_cleanup (&update_opts);
@@ -570,6 +577,7 @@ mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
570577
&update_opts.arrayFilters,
571578
&update_opts.extra,
572579
true /* multi */,
580+
NULL /* sort */,
573581
error);
574582

575583
_mongoc_bulk_update_many_opts_cleanup (&update_opts);
@@ -674,7 +682,8 @@ mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk,
674682
GOTO (done);
675683
}
676684

677-
_mongoc_bulk_operation_update_append (bulk, selector, document, update_opts, NULL, &repl_opts.extra);
685+
_mongoc_bulk_operation_update_append (
686+
bulk, selector, document, update_opts, NULL, &repl_opts.extra, &repl_opts.sort);
678687
ret = true;
679688

680689
done:

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ struct _mongoc_bulkwrite_updateoneopts_t {
326326
bson_t *collation;
327327
bson_value_t hint;
328328
mongoc_optional_t upsert;
329+
bson_t *sort;
329330
};
330331

331332
mongoc_bulkwrite_updateoneopts_t *
@@ -361,6 +362,13 @@ mongoc_bulkwrite_updateoneopts_set_upsert (mongoc_bulkwrite_updateoneopts_t *sel
361362
mongoc_optional_set_value (&self->upsert, upsert);
362363
}
363364
void
365+
mongoc_bulkwrite_updateoneopts_set_sort (mongoc_bulkwrite_updateoneopts_t *self, const bson_t *sort)
366+
{
367+
BSON_ASSERT_PARAM (self);
368+
BSON_OPTIONAL_PARAM (sort);
369+
set_bson_opt (&self->sort, sort);
370+
}
371+
void
364372
mongoc_bulkwrite_updateoneopts_destroy (mongoc_bulkwrite_updateoneopts_t *self)
365373
{
366374
if (!self) {
@@ -369,6 +377,7 @@ mongoc_bulkwrite_updateoneopts_destroy (mongoc_bulkwrite_updateoneopts_t *self)
369377
bson_destroy (self->arrayfilters);
370378
bson_destroy (self->collation);
371379
bson_value_destroy (&self->hint);
380+
bson_destroy (self->sort);
372381
bson_free (self);
373382
}
374383

@@ -422,6 +431,9 @@ mongoc_bulkwrite_append_updateone (mongoc_bulkwrite_t *self,
422431
if (mongoc_optional_is_set (&opts->upsert)) {
423432
BSON_ASSERT (BSON_APPEND_BOOL (&op, "upsert", mongoc_optional_value (&opts->upsert)));
424433
}
434+
if (opts->sort) {
435+
BSON_ASSERT (BSON_APPEND_DOCUMENT (&op, "sort", opts->sort));
436+
}
425437

426438
BSON_ASSERT (_mongoc_buffer_append (&self->ops, bson_get_data (&op), op.len));
427439

@@ -436,6 +448,7 @@ struct _mongoc_bulkwrite_replaceoneopts_t {
436448
bson_t *collation;
437449
bson_value_t hint;
438450
mongoc_optional_t upsert;
451+
bson_t *sort;
439452
};
440453

441454
mongoc_bulkwrite_replaceoneopts_t *
@@ -464,13 +477,21 @@ mongoc_bulkwrite_replaceoneopts_set_upsert (mongoc_bulkwrite_replaceoneopts_t *s
464477
mongoc_optional_set_value (&self->upsert, upsert);
465478
}
466479
void
480+
mongoc_bulkwrite_replaceoneopts_set_sort (mongoc_bulkwrite_replaceoneopts_t *self, const bson_t *sort)
481+
{
482+
BSON_ASSERT_PARAM (self);
483+
BSON_OPTIONAL_PARAM (sort);
484+
set_bson_opt (&self->sort, sort);
485+
}
486+
void
467487
mongoc_bulkwrite_replaceoneopts_destroy (mongoc_bulkwrite_replaceoneopts_t *self)
468488
{
469489
if (!self) {
470490
return;
471491
}
472492
bson_destroy (self->collation);
473493
bson_value_destroy (&self->hint);
494+
bson_destroy (self->sort);
474495
bson_free (self);
475496
}
476497

@@ -542,6 +563,9 @@ mongoc_bulkwrite_append_replaceone (mongoc_bulkwrite_t *self,
542563
if (mongoc_optional_is_set (&opts->upsert)) {
543564
BSON_ASSERT (BSON_APPEND_BOOL (&op, "upsert", mongoc_optional_value (&opts->upsert)));
544565
}
566+
if (opts->sort) {
567+
BSON_ASSERT (BSON_APPEND_DOCUMENT (&op, "sort", opts->sort));
568+
}
545569

546570
BSON_ASSERT (_mongoc_buffer_append (&self->ops, bson_get_data (&op), op.len));
547571

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ mongoc_bulkwrite_updateoneopts_set_hint (mongoc_bulkwrite_updateoneopts_t *self,
151151
MONGOC_EXPORT (void)
152152
mongoc_bulkwrite_updateoneopts_set_upsert (mongoc_bulkwrite_updateoneopts_t *self, bool upsert);
153153
MONGOC_EXPORT (void)
154+
mongoc_bulkwrite_updateoneopts_set_sort (mongoc_bulkwrite_updateoneopts_t *self, const bson_t *sort);
155+
MONGOC_EXPORT (void)
154156
mongoc_bulkwrite_updateoneopts_destroy (mongoc_bulkwrite_updateoneopts_t *self);
155157
MONGOC_EXPORT (bool)
156158
mongoc_bulkwrite_append_updateone (mongoc_bulkwrite_t *self,
@@ -191,6 +193,8 @@ mongoc_bulkwrite_replaceoneopts_set_hint (mongoc_bulkwrite_replaceoneopts_t *sel
191193
MONGOC_EXPORT (void)
192194
mongoc_bulkwrite_replaceoneopts_set_upsert (mongoc_bulkwrite_replaceoneopts_t *self, bool upsert);
193195
MONGOC_EXPORT (void)
196+
mongoc_bulkwrite_replaceoneopts_set_sort (mongoc_bulkwrite_replaceoneopts_t *self, const bson_t *sort);
197+
MONGOC_EXPORT (void)
194198
mongoc_bulkwrite_replaceoneopts_destroy (mongoc_bulkwrite_replaceoneopts_t *self);
195199
MONGOC_EXPORT (bool)
196200
mongoc_bulkwrite_append_replaceone (mongoc_bulkwrite_t *self,

src/libmongoc/src/mongoc/mongoc-collection.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,7 @@ _mongoc_collection_update_or_replace (mongoc_collection_t *collection,
20172017
bool multi,
20182018
bool bypass,
20192019
const bson_t *array_filters,
2020+
const bson_t *sort,
20202021
bson_t *extra,
20212022
bson_t *reply,
20222023
bson_error_t *error)
@@ -2058,6 +2059,10 @@ _mongoc_collection_update_or_replace (mongoc_collection_t *collection,
20582059
bson_append_array (extra, "arrayFilters", 12, array_filters);
20592060
}
20602061

2062+
if (!bson_empty0 (sort)) {
2063+
bson_append_document (extra, "sort", 4, sort);
2064+
}
2065+
20612066
if (multi) {
20622067
bson_append_bool (extra, "multi", 5, true);
20632068
}
@@ -2180,6 +2185,7 @@ mongoc_collection_update_one (mongoc_collection_t *collection,
21802185
false /* multi */,
21812186
update_one_opts.update.bypass,
21822187
&update_one_opts.arrayFilters,
2188+
&update_one_opts.sort,
21832189
&update_one_opts.extra,
21842190
reply,
21852191
error);
@@ -2224,6 +2230,7 @@ mongoc_collection_update_many (mongoc_collection_t *collection,
22242230
true /* multi */,
22252231
update_many_opts.update.bypass,
22262232
&update_many_opts.arrayFilters,
2233+
NULL /* sort */,
22272234
&update_many_opts.extra,
22282235
reply,
22292236
error);
@@ -2268,6 +2275,7 @@ mongoc_collection_replace_one (mongoc_collection_t *collection,
22682275
false /* multi */,
22692276
replace_one_opts.update.bypass,
22702277
NULL,
2278+
&replace_one_opts.sort,
22712279
&replace_one_opts.extra,
22722280
reply,
22732281
error);

src/libmongoc/src/mongoc/mongoc-opts-private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ typedef struct _mongoc_delete_many_opts_t {
8484
typedef struct _mongoc_update_one_opts_t {
8585
mongoc_update_opts_t update;
8686
bson_t arrayFilters;
87+
bson_t sort;
8788
bson_t extra;
8889
} mongoc_update_one_opts_t;
8990

@@ -95,6 +96,7 @@ typedef struct _mongoc_update_many_opts_t {
9596

9697
typedef struct _mongoc_replace_one_opts_t {
9798
mongoc_update_opts_t update;
99+
bson_t sort;
98100
bson_t extra;
99101
} mongoc_replace_one_opts_t;
100102

@@ -123,6 +125,7 @@ typedef struct _mongoc_bulk_update_opts_t {
123125

124126
typedef struct _mongoc_bulk_update_one_opts_t {
125127
mongoc_bulk_update_opts_t update;
128+
bson_t sort;
126129
bson_t arrayFilters;
127130
bson_t extra;
128131
} mongoc_bulk_update_one_opts_t;
@@ -135,6 +138,7 @@ typedef struct _mongoc_bulk_update_many_opts_t {
135138

136139
typedef struct _mongoc_bulk_replace_one_opts_t {
137140
mongoc_bulk_update_opts_t update;
141+
bson_t sort;
138142
bson_t extra;
139143
} mongoc_bulk_replace_one_opts_t;
140144

0 commit comments

Comments
 (0)