@@ -7,9 +7,14 @@ use typed_builder::TypedBuilder;
7
7
8
8
use crate :: {
9
9
bson:: { rawdoc, Array , Bson , Document , RawDocumentBuf } ,
10
- bson_compat:: cstr,
11
- bson_util:: { get_or_prepend_id_field, replacement_document_check, update_document_check} ,
12
- error:: Result ,
10
+ bson_compat:: { cstr, serialize_to_raw_document_buf} ,
11
+ bson_util:: {
12
+ extend_raw_document_buf,
13
+ get_or_prepend_id_field,
14
+ replacement_document_check,
15
+ update_document_check,
16
+ } ,
17
+ error:: { Error , Result } ,
13
18
options:: { UpdateModifications , WriteConcern } ,
14
19
serde_util:: { serialize_bool_or_true, write_concern_is_empty} ,
15
20
Collection ,
@@ -371,9 +376,17 @@ impl WriteModel {
371
376
}
372
377
}
373
378
374
- /// Returns the operation-specific fields that should be included in this model's entry in the
375
- /// ops array. Also returns an inserted ID if this is an insert operation.
376
- pub ( crate ) fn get_ops_document_contents ( & self ) -> Result < ( RawDocumentBuf , Option < Bson > ) > {
379
+ /// Constructs the ops document for this write model given the nsInfo array index.
380
+ pub ( crate ) fn get_ops_document (
381
+ & self ,
382
+ ns_info_index : usize ,
383
+ ) -> Result < ( RawDocumentBuf , Option < Bson > ) > {
384
+ // The maximum number of namespaces allowed in a bulkWrite command is much lower than
385
+ // i32::MAX, so this should never fail.
386
+ let index = i32:: try_from ( ns_info_index)
387
+ . map_err ( |_| Error :: internal ( "nsInfo index exceeds i32::MAX" ) ) ?;
388
+ let mut ops_document = rawdoc ! { self . operation_name( ) : index } ;
389
+
377
390
if let Self :: UpdateOne ( UpdateOneModel { update, .. } )
378
391
| Self :: UpdateMany ( UpdateManyModel { update, .. } ) = self
379
392
{
@@ -384,22 +397,19 @@ impl WriteModel {
384
397
replacement_document_check ( replacement) ?;
385
398
}
386
399
387
- let ( mut model_document, inserted_id) = match self {
388
- Self :: InsertOne ( model) => {
389
- let mut insert_document = RawDocumentBuf :: try_from ( & model. document ) ?;
390
- let inserted_id = get_or_prepend_id_field ( & mut insert_document) ?;
391
- ( rawdoc ! { "document" : insert_document } , Some ( inserted_id) )
392
- }
393
- _ => {
394
- let model_document = crate :: bson_compat:: serialize_to_raw_document_buf ( & self ) ?;
395
- ( model_document, None )
396
- }
397
- } ;
398
-
399
400
if let Some ( multi) = self . multi ( ) {
400
- model_document . append ( cstr ! ( "multi" ) , multi) ;
401
+ ops_document . append ( cstr ! ( "multi" ) , multi) ;
401
402
}
402
403
403
- Ok ( ( model_document, inserted_id) )
404
+ if let Self :: InsertOne ( model) = self {
405
+ let mut insert_document = RawDocumentBuf :: try_from ( & model. document ) ?;
406
+ let inserted_id = get_or_prepend_id_field ( & mut insert_document) ?;
407
+ ops_document. append ( cstr ! ( "document" ) , insert_document) ;
408
+ Ok ( ( ops_document, Some ( inserted_id) ) )
409
+ } else {
410
+ let model = serialize_to_raw_document_buf ( & self ) ?;
411
+ extend_raw_document_buf ( & mut ops_document, model) ?;
412
+ Ok ( ( ops_document, None ) )
413
+ }
404
414
}
405
415
}
0 commit comments