1- import { type Document } from 'bson' ;
2-
1+ import { MongoClientBulkWriteExecutionError , ServerType } from '../../beta' ;
32import { ClientBulkWriteCursorResponse } from '../../cmap/wire_protocol/responses' ;
43import type { Server } from '../../sdam/server' ;
54import type { ClientSession } from '../../sessions' ;
65import { MongoDBNamespace } from '../../utils' ;
76import { CommandOperation } from '../command' ;
87import { Aspect , defineAspects } from '../operation' ;
8+ import { type ClientBulkWriteCommandBuilder } from './command_builder' ;
99import { type ClientBulkWriteOptions } from './common' ;
1010
1111/**
1212 * Executes a single client bulk write operation within a potential batch.
1313 * @internal
1414 */
1515export class ClientBulkWriteOperation extends CommandOperation < ClientBulkWriteCursorResponse > {
16- command : Document ;
16+ commandBuilder : ClientBulkWriteCommandBuilder ;
1717 override options : ClientBulkWriteOptions ;
1818
1919 override get commandName ( ) {
2020 return 'bulkWrite' as const ;
2121 }
2222
23- constructor ( command : Document , options : ClientBulkWriteOptions ) {
23+ constructor ( commandBuilder : ClientBulkWriteCommandBuilder , options : ClientBulkWriteOptions ) {
2424 super ( undefined , options ) ;
25- this . command = command ;
25+ this . commandBuilder = commandBuilder ;
2626 this . options = options ;
2727 this . ns = new MongoDBNamespace ( 'admin' , '$cmd' ) ;
2828 }
@@ -37,9 +37,45 @@ export class ClientBulkWriteOperation extends CommandOperation<ClientBulkWriteCu
3737 server : Server ,
3838 session : ClientSession | undefined
3939 ) : Promise < ClientBulkWriteCursorResponse > {
40- return await super . executeCommand ( server , session , this . command , ClientBulkWriteCursorResponse ) ;
40+ let command ;
41+
42+ if ( server . description . type === ServerType . LoadBalancer ) {
43+ if ( session ) {
44+ // Checkout a connection to build the command.
45+ const connection = await server . pool . checkOut ( ) ;
46+ // Pin the connection to the session so it get used to execute the command and we do not
47+ // perform a double check-in/check-out.
48+ session . pin ( connection ) ;
49+ command = this . commandBuilder . buildBatch (
50+ connection . hello ?. maxMessageSizeBytes ,
51+ connection . hello ?. maxWriteBatchSize
52+ ) ;
53+ } else {
54+ throw new MongoClientBulkWriteExecutionError (
55+ 'Session provided to the client bulk write operation must be present.'
56+ ) ;
57+ }
58+ } else {
59+ // At this point we have a server and the auto connect code has already
60+ // run in executeOperation, so the server description will be populated.
61+ // We can use that to build the command.
62+ if ( ! server . description . maxWriteBatchSize || ! server . description . maxMessageSizeBytes ) {
63+ throw new MongoClientBulkWriteExecutionError (
64+ 'In order to execute a client bulk write, both maxWriteBatchSize and maxMessageSizeBytes must be provided by the servers hello response.'
65+ ) ;
66+ }
67+ command = this . commandBuilder . buildBatch (
68+ server . description . maxMessageSizeBytes ,
69+ server . description . maxWriteBatchSize
70+ ) ;
71+ }
72+ return await super . executeCommand ( server , session , command , ClientBulkWriteCursorResponse ) ;
4173 }
4274}
4375
4476// Skipping the collation as it goes on the individual ops.
45- defineAspects ( ClientBulkWriteOperation , [ Aspect . WRITE_OPERATION , Aspect . SKIP_COLLATION ] ) ;
77+ defineAspects ( ClientBulkWriteOperation , [
78+ Aspect . WRITE_OPERATION ,
79+ Aspect . SKIP_COLLATION ,
80+ Aspect . CURSOR_CREATING
81+ ] ) ;
0 commit comments