@@ -7,9 +7,14 @@ use typed_builder::TypedBuilder;
77
88use crate :: {
99 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 } ,
1318 options:: { UpdateModifications , WriteConcern } ,
1419 serde_util:: { serialize_bool_or_true, write_concern_is_empty} ,
1520 Collection ,
@@ -371,9 +376,17 @@ impl WriteModel {
371376 }
372377 }
373378
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+
377390 if let Self :: UpdateOne ( UpdateOneModel { update, .. } )
378391 | Self :: UpdateMany ( UpdateManyModel { update, .. } ) = self
379392 {
@@ -384,22 +397,19 @@ impl WriteModel {
384397 replacement_document_check ( replacement) ?;
385398 }
386399
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-
399400 if let Some ( multi) = self . multi ( ) {
400- model_document . append ( cstr ! ( "multi" ) , multi) ;
401+ ops_document . append ( cstr ! ( "multi" ) , multi) ;
401402 }
402403
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+ }
404414 }
405415}
0 commit comments