@@ -14,13 +14,11 @@ import type { CollationOptions, CommandOperationOptions } from '../operations/co
1414import { DeleteOperation , type DeleteStatement , makeDeleteStatement } from '../operations/delete' ;
1515import { executeOperation } from '../operations/execute_operation' ;
1616import { InsertOperation } from '../operations/insert' ;
17- import { AbstractOperation , type Hint } from '../operations/operation' ;
17+ import { type Hint } from '../operations/operation' ;
1818import { makeUpdateStatement , UpdateOperation , type UpdateStatement } from '../operations/update' ;
19- import type { Server } from '../sdam/server' ;
2019import type { Topology } from '../sdam/topology' ;
21- import type { ClientSession } from '../sessions' ;
2220import { type Sort } from '../sort' ;
23- import { type TimeoutContext } from '../timeout' ;
21+ import { TimeoutContext } from '../timeout' ;
2422import {
2523 applyRetryableWrites ,
2624 getTopology ,
@@ -854,40 +852,6 @@ export interface BulkWriteOptions extends CommandOperationOptions {
854852 timeoutContext ?: TimeoutContext ;
855853}
856854
857- /**
858- * TODO(NODE-4063)
859- * BulkWrites merge complexity is implemented in executeCommands
860- * This provides a vehicle to treat bulkOperations like any other operation (hence "shim")
861- * We would like this logic to simply live inside the BulkWriteOperation class
862- * @internal
863- */
864- export class BulkWriteShimOperation extends AbstractOperation {
865- bulkOperation : BulkOperationBase ;
866- constructor ( bulkOperation : BulkOperationBase , options : BulkWriteOptions ) {
867- super ( options ) ;
868- this . bulkOperation = bulkOperation ;
869- }
870-
871- get commandName ( ) : string {
872- return 'bulkWrite' as const ;
873- }
874-
875- async execute (
876- _server : Server ,
877- session : ClientSession | undefined ,
878- timeoutContext : TimeoutContext
879- ) : Promise < any > {
880- if ( this . options . session == null ) {
881- // An implicit session could have been created by 'executeOperation'
882- // So if we stick it on finalOptions here, each bulk operation
883- // will use this same session, it'll be passed in the same way
884- // an explicit session would be
885- this . options . session = session ;
886- }
887- return await executeCommands ( this . bulkOperation , { ...this . options , timeoutContext } ) ;
888- }
889- }
890-
891855/** @public */
892856export abstract class BulkOperationBase {
893857 isOrdered : boolean ;
@@ -1208,10 +1172,26 @@ export abstract class BulkOperationBase {
12081172 }
12091173
12101174 this . s . executed = true ;
1211- const finalOptions = { ...this . s . options , ...options } ;
1212- const operation = new BulkWriteShimOperation ( this , finalOptions ) ;
1175+ const finalOptions = resolveOptions ( this . collection , { ...this . s . options , ...options } ) ;
1176+
1177+ // if there is no timeoutContext provided, create a timeoutContext and use it for
1178+ // all batches in the bulk operation
1179+ finalOptions . timeoutContext ??= TimeoutContext . create ( {
1180+ session : finalOptions . session ,
1181+ timeoutMS : finalOptions . timeoutMS ,
1182+ serverSelectionTimeoutMS : this . collection . client . s . options . serverSelectionTimeoutMS ,
1183+ waitQueueTimeoutMS : this . collection . client . s . options . waitQueueTimeoutMS
1184+ } ) ;
1185+
1186+ if ( finalOptions . session == null ) {
1187+ // if there is not an explicit session provided to `execute()`, create
1188+ // an implicit session and use that for all batches in the bulk operation
1189+ return await this . collection . client . withSession ( { explicit : false } , async session => {
1190+ return await executeCommands ( this , { ...finalOptions , session } ) ;
1191+ } ) ;
1192+ }
12131193
1214- return await executeOperation ( this . s . collection . client , operation , finalOptions . timeoutContext ) ;
1194+ return await executeCommands ( this , { ... finalOptions } ) ;
12151195 }
12161196
12171197 /**
0 commit comments