Skip to content

Commit ca9dccb

Browse files
Utkarsh Mehtautkmehta
authored andcommitted
RUST-362 Add hint option to findAndModify operations
1 parent 357fca4 commit ca9dccb

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

src/coll/options.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,11 @@ pub struct FindOneAndReplaceOptions {
356356
/// information on how to use this option.
357357
#[builder(default)]
358358
pub collation: Option<Collation>,
359+
360+
/// The index to use for the operation.
361+
/// Only available in MongoDB 4.4+.
362+
#[builder(default)]
363+
pub hint: Option<Hint>,
359364
}
360365

361366
/// Specifies the options to a
@@ -408,6 +413,11 @@ pub struct FindOneAndUpdateOptions {
408413
/// information on how to use this option.
409414
#[builder(default)]
410415
pub collation: Option<Collation>,
416+
417+
/// The index to use for the operation.
418+
/// Only available in MongoDB 4.4+.
419+
#[builder(default)]
420+
pub hint: Option<Hint>,
411421
}
412422

413423
/// Specifies the options to a [`Collection::aggregate`](../struct.Collection.html#method.aggregate)

src/operation/find_and_modify/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl FindAndModifyOptions {
103103
.sort(opts.sort)
104104
.upsert(opts.upsert)
105105
.write_concern(opts.write_concern)
106+
.hint(opts.hint)
106107
.build()
107108
}
108109

@@ -121,6 +122,7 @@ impl FindAndModifyOptions {
121122
.sort(opts.sort)
122123
.upsert(opts.upsert)
123124
.write_concern(opts.write_concern)
125+
.hint(opts.hint)
124126
.build()
125127
}
126128
}

src/operation/find_and_modify/test.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
FindOneAndDeleteOptions,
1111
FindOneAndReplaceOptions,
1212
FindOneAndUpdateOptions,
13+
Hint,
1314
UpdateModifications,
1415
},
1516
Namespace,
@@ -26,6 +27,48 @@ fn empty_delete() -> FindAndModify {
2627
FindAndModify::with_delete(ns, filter, None)
2728
}
2829

30+
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
31+
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
32+
async fn build_with_delete_hint() {
33+
let ns = Namespace {
34+
db: "test_db".to_string(),
35+
coll: "test_coll".to_string(),
36+
};
37+
let filter = doc! {
38+
"x": 2,
39+
"y": { "$gt": 1 },
40+
};
41+
42+
let options = FindOneAndDeleteOptions {
43+
hint: Some(Hint::Keys(doc! { "x": 1, "y": -1 })),
44+
..Default::default()
45+
};
46+
47+
let op = FindAndModify::with_delete(ns, filter.clone(), Some(options));
48+
49+
let description = StreamDescription::new_testing();
50+
let mut cmd = op.build(&description).unwrap();
51+
52+
assert_eq!(cmd.name.as_str(), "findAndModify");
53+
assert_eq!(cmd.target_db.as_str(), "test_db");
54+
assert_eq!(cmd.read_pref.as_ref(), None);
55+
56+
let mut expected_body = doc! {
57+
"findAndModify": "test_coll",
58+
"query": filter,
59+
"hint": {
60+
"x": 1,
61+
"y": -1,
62+
},
63+
"remove": true
64+
};
65+
66+
bson_util::sort_document(&mut cmd.body);
67+
bson_util::sort_document(&mut expected_body);
68+
69+
assert_eq!(cmd.body, expected_body);
70+
}
71+
2972
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
3073
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
3174
async fn build_with_delete_no_options() {
@@ -156,6 +199,52 @@ fn empty_replace() -> FindAndModify {
156199
FindAndModify::with_replace(ns, filter, replacement, None).unwrap()
157200
}
158201

202+
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
203+
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
204+
async fn build_with_replace_hint() {
205+
let ns = Namespace {
206+
db: "test_db".to_string(),
207+
coll: "test_coll".to_string(),
208+
};
209+
let filter = doc! { "x": { "$gt": 1 } };
210+
let replacement = doc! { "x": { "inc": 1 } };
211+
let options = FindOneAndReplaceOptions {
212+
hint: Some(Hint::Keys(doc! { "x": 1, "y": -1 })),
213+
upsert: Some(false),
214+
bypass_document_validation: Some(true),
215+
return_document: Some(ReturnDocument::After),
216+
..Default::default()
217+
};
218+
219+
let op = FindAndModify::with_replace(ns, filter.clone(), replacement.clone(), Some(options))
220+
.unwrap();
221+
222+
let description = StreamDescription::new_testing();
223+
let mut cmd = op.build(&description).unwrap();
224+
225+
assert_eq!(cmd.name.as_str(), "findAndModify");
226+
assert_eq!(cmd.target_db.as_str(), "test_db");
227+
assert_eq!(cmd.read_pref.as_ref(), None);
228+
229+
let mut expected_body = doc! {
230+
"findAndModify": "test_coll",
231+
"query": filter,
232+
"update": replacement,
233+
"upsert": false,
234+
"bypassDocumentValidation": true,
235+
"new": true,
236+
"hint": {
237+
"x": 1,
238+
"y": -1,
239+
},
240+
};
241+
242+
bson_util::sort_document(&mut cmd.body);
243+
bson_util::sort_document(&mut expected_body);
244+
245+
assert_eq!(cmd.body, expected_body);
246+
}
247+
159248
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
160249
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
161250
async fn build_with_replace_no_options() {
@@ -292,6 +381,49 @@ fn empty_update() -> FindAndModify {
292381
FindAndModify::with_update(ns, filter, update, None).unwrap()
293382
}
294383

384+
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
385+
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
386+
async fn build_with_update_hint() {
387+
let ns = Namespace {
388+
db: "test_db".to_string(),
389+
coll: "test_coll".to_string(),
390+
};
391+
let filter = doc! { "x": { "$gt": 1 } };
392+
let update = UpdateModifications::Document(doc! { "$x": { "$inc": 1 } });
393+
let options = FindOneAndUpdateOptions {
394+
hint: Some(Hint::Keys(doc! { "x": 1, "y": -1 })),
395+
upsert: Some(false),
396+
bypass_document_validation: Some(true),
397+
..Default::default()
398+
};
399+
400+
let op = FindAndModify::with_update(ns, filter.clone(), update.clone(), Some(options)).unwrap();
401+
402+
let description = StreamDescription::new_testing();
403+
let mut cmd = op.build(&description).unwrap();
404+
405+
assert_eq!(cmd.name.as_str(), "findAndModify");
406+
assert_eq!(cmd.target_db.as_str(), "test_db");
407+
assert_eq!(cmd.read_pref.as_ref(), None);
408+
409+
let mut expected_body = doc! {
410+
"findAndModify": "test_coll",
411+
"query": filter,
412+
"update": update.to_bson(),
413+
"upsert": false,
414+
"bypassDocumentValidation": true,
415+
"hint": {
416+
"x": 1,
417+
"y": -1,
418+
},
419+
};
420+
421+
bson_util::sort_document(&mut cmd.body);
422+
bson_util::sort_document(&mut expected_body);
423+
424+
assert_eq!(cmd.body, expected_body);
425+
}
426+
295427
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
296428
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
297429
async fn build_with_update_no_options() {

0 commit comments

Comments
 (0)