1+ import { type Connection } from '..' ;
12import type { Document } from '../bson' ;
3+ import { MongoDBResponse } from '../cmap/wire_protocol/responses' ;
24import type { Collection } from '../collection' ;
35import { MongoCompatibilityError , MongoInvalidArgumentError } from '../error' ;
46import { ReadPreference } from '../read_preference' ;
5- import type { Server } from '../sdam/server' ;
67import type { ClientSession } from '../sessions' ;
78import { formatSort , type Sort , type SortForCmd } from '../sort' ;
8- import { type TimeoutContext } from '../timeout' ;
9- import { decorateWithCollation , hasAtomicOperators , maxWireVersion } from '../utils' ;
9+ import { decorateWithCollation , hasAtomicOperators } from '../utils' ;
1010import { type WriteConcern , type WriteConcernSettings } from '../write_concern' ;
11- import { CommandOperation , type CommandOperationOptions } from './command' ;
11+ import { type CommandOperationOptions , ModernizedCommandOperation } from './command' ;
1212import { Aspect , defineAspects } from './operation' ;
1313
1414/** @public */
@@ -120,9 +120,9 @@ function configureFindAndModifyCmdBaseUpdateOpts(
120120}
121121
122122/** @internal */
123- export class FindAndModifyOperation extends CommandOperation < Document > {
123+ export class FindAndModifyOperation extends ModernizedCommandOperation < Document > {
124+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse ;
124125 override options : FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions ;
125- cmdBase : FindAndModifyCmdBase ;
126126 collection : Collection ;
127127 query : Document ;
128128 doc ?: Document ;
@@ -133,8 +133,26 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
133133 options : FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions
134134 ) {
135135 super ( collection , options ) ;
136- this . options = options ?? { } ;
137- this . cmdBase = {
136+ this . options = options ;
137+ // force primary read preference
138+ this . readPreference = ReadPreference . primary ;
139+
140+ this . collection = collection ;
141+ this . query = query ;
142+ }
143+
144+ override get commandName ( ) {
145+ return 'findAndModify' as const ;
146+ }
147+
148+ override buildCommandDocument (
149+ _connection : Connection ,
150+ _session ?: ClientSession
151+ ) : Document & FindAndModifyCmdBase {
152+ const options = this . options ;
153+ const command : Document & FindAndModifyCmdBase = {
154+ findAndModify : this . collection . collectionName ,
155+ query : this . query ,
138156 remove : false ,
139157 new : false ,
140158 upsert : false
@@ -144,77 +162,51 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
144162
145163 const sort = formatSort ( options . sort ) ;
146164 if ( sort ) {
147- this . cmdBase . sort = sort ;
165+ command . sort = sort ;
148166 }
149167
150168 if ( options . projection ) {
151- this . cmdBase . fields = options . projection ;
169+ command . fields = options . projection ;
152170 }
153171
154172 if ( options . maxTimeMS ) {
155- this . cmdBase . maxTimeMS = options . maxTimeMS ;
173+ command . maxTimeMS = options . maxTimeMS ;
156174 }
157175
158176 // Decorate the findAndModify command with the write Concern
159177 if ( options . writeConcern ) {
160- this . cmdBase . writeConcern = options . writeConcern ;
178+ command . writeConcern = options . writeConcern ;
161179 }
162180
163181 if ( options . let ) {
164- this . cmdBase . let = options . let ;
182+ command . let = options . let ;
165183 }
166184
167185 // we check for undefined specifically here to allow falsy values
168186 // eslint-disable-next-line no-restricted-syntax
169187 if ( options . comment !== undefined ) {
170- this . cmdBase . comment = options . comment ;
188+ command . comment = options . comment ;
171189 }
172190
173- // force primary read preference
174- this . readPreference = ReadPreference . primary ;
175-
176- this . collection = collection ;
177- this . query = query ;
178- }
179-
180- override get commandName ( ) {
181- return 'findAndModify' as const ;
182- }
183-
184- override async execute (
185- server : Server ,
186- session : ClientSession | undefined ,
187- timeoutContext : TimeoutContext
188- ) : Promise < Document > {
189- const coll = this . collection ;
190- const query = this . query ;
191- const options = { ...this . options , ...this . bsonOptions } ;
192-
193- // Create findAndModify command object
194- const cmd : Document = {
195- findAndModify : coll . collectionName ,
196- query : query ,
197- ...this . cmdBase
198- } ;
199-
200- decorateWithCollation ( cmd , coll , options ) ;
191+ decorateWithCollation ( command , this . collection , options ) ;
201192
202193 if ( options . hint ) {
203- // TODO: once this method becomes a CommandOperation we will have the server
204- // in place to check.
205194 const unacknowledgedWrite = this . writeConcern ?. w === 0 ;
206- if ( unacknowledgedWrite || maxWireVersion ( server ) < 8 ) {
195+ if ( unacknowledgedWrite ) {
207196 throw new MongoCompatibilityError (
208197 'The current topology does not support a hint on findAndModify commands'
209198 ) ;
210199 }
211200
212- cmd . hint = options . hint ;
201+ command . hint = options . hint ;
213202 }
214203
215- // Execute the command
216- const result = await super . executeCommand ( server , session , cmd , timeoutContext ) ;
217- return options . includeResultMetadata ? result : ( result . value ?? null ) ;
204+ return command ;
205+ }
206+
207+ override handleOk ( response : InstanceType < typeof this . SERVER_COMMAND_RESPONSE_TYPE > ) : Document {
208+ const result = super . handleOk ( response ) ;
209+ return this . options . includeResultMetadata ? result : ( result . value ?? null ) ;
218210 }
219211}
220212
@@ -227,12 +219,21 @@ export class FindOneAndDeleteOperation extends FindAndModifyOperation {
227219 }
228220
229221 super ( collection , filter , options ) ;
230- this . cmdBase . remove = true ;
222+ }
223+
224+ override buildCommandDocument (
225+ connection : Connection ,
226+ session ?: ClientSession
227+ ) : Document & FindAndModifyCmdBase {
228+ const document = super . buildCommandDocument ( connection , session ) ;
229+ document . remove = true ;
230+ return document ;
231231 }
232232}
233233
234234/** @internal */
235235export class FindOneAndReplaceOperation extends FindAndModifyOperation {
236+ private replacement : Document ;
236237 constructor (
237238 collection : Collection ,
238239 filter : Document ,
@@ -252,13 +253,25 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
252253 }
253254
254255 super ( collection , filter , options ) ;
255- this . cmdBase . update = replacement ;
256- configureFindAndModifyCmdBaseUpdateOpts ( this . cmdBase , options ) ;
256+ this . replacement = replacement ;
257+ }
258+
259+ override buildCommandDocument (
260+ connection : Connection ,
261+ session ?: ClientSession
262+ ) : Document & FindAndModifyCmdBase {
263+ const document = super . buildCommandDocument ( connection , session ) ;
264+ document . update = this . replacement ;
265+ configureFindAndModifyCmdBaseUpdateOpts ( document , this . options ) ;
266+ return document ;
257267 }
258268}
259269
260270/** @internal */
261271export class FindOneAndUpdateOperation extends FindAndModifyOperation {
272+ override options : FindOneAndUpdateOptions ;
273+
274+ private update : Document ;
262275 constructor (
263276 collection : Collection ,
264277 filter : Document ,
@@ -278,12 +291,23 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
278291 }
279292
280293 super ( collection , filter , options ) ;
281- this . cmdBase . update = update ;
282- configureFindAndModifyCmdBaseUpdateOpts ( this . cmdBase , options ) ;
294+ this . update = update ;
295+ this . options = options ;
296+ }
283297
284- if ( options . arrayFilters ) {
285- this . cmdBase . arrayFilters = options . arrayFilters ;
298+ override buildCommandDocument (
299+ connection : Connection ,
300+ session ?: ClientSession
301+ ) : Document & FindAndModifyCmdBase {
302+ const document = super . buildCommandDocument ( connection , session ) ;
303+ document . update = this . update ;
304+ configureFindAndModifyCmdBaseUpdateOpts ( document , this . options ) ;
305+
306+ if ( this . options . arrayFilters ) {
307+ document . arrayFilters = this . options . arrayFilters ;
286308 }
309+
310+ return document ;
287311 }
288312}
289313
0 commit comments