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 { hasAtomicOperators , maxWireVersion } 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,12 +120,12 @@ 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 ;
125+
124126 override options : FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions ;
125- cmdBase : FindAndModifyCmdBase ;
126127 collection : Collection ;
127128 query : Document ;
128- doc ?: Document ;
129129
130130 constructor (
131131 collection : Collection ,
@@ -134,87 +134,84 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
134134 ) {
135135 super ( collection , options ) ;
136136 this . options = options ?? { } ;
137- this . cmdBase = {
137+
138+ options . includeResultMetadata ??= false ;
139+
140+ // force primary read preference
141+ this . readPreference = ReadPreference . primary ;
142+
143+ this . collection = collection ;
144+ this . query = query ;
145+ }
146+
147+ override get commandName ( ) {
148+ return 'findAndModify' as const ;
149+ }
150+
151+ override buildCommandDocument (
152+ connection : Connection ,
153+ _session ?: ClientSession
154+ ) : FindAndModifyCmdBase {
155+ const coll = this . collection ;
156+ const query = this . query ;
157+ const options = this . options ;
158+
159+ // Create findAndModify command object
160+ const command : FindAndModifyCmdBase & Document = {
161+ findAndModify : coll . collectionName ,
162+ query : query ,
138163 remove : false ,
139164 new : false ,
140165 upsert : false
141166 } ;
142167
143- options . includeResultMetadata ??= false ;
144-
145168 const sort = formatSort ( options . sort ) ;
146169 if ( sort ) {
147- this . cmdBase . sort = sort ;
170+ command . sort = sort ;
148171 }
149172
150173 if ( options . projection ) {
151- this . cmdBase . fields = options . projection ;
174+ command . fields = options . projection ;
152175 }
153176
154177 if ( options . maxTimeMS ) {
155- this . cmdBase . maxTimeMS = options . maxTimeMS ;
178+ command . maxTimeMS = options . maxTimeMS ;
156179 }
157180
158181 // Decorate the findAndModify command with the write Concern
159182 if ( options . writeConcern ) {
160- this . cmdBase . writeConcern = options . writeConcern ;
183+ command . writeConcern = options . writeConcern ;
161184 }
162185
163186 if ( options . let ) {
164- this . cmdBase . let = options . let ;
187+ command . let = options . let ;
165188 }
166189
167190 // we check for undefined specifically here to allow falsy values
168191 // eslint-disable-next-line no-restricted-syntax
169192 if ( options . comment !== undefined ) {
170- this . cmdBase . comment = options . comment ;
193+ command . comment = options . comment ;
171194 }
172195
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 ) ;
201-
202196 if ( options . hint ) {
203197 // TODO: once this method becomes a CommandOperation we will have the server
204198 // in place to check.
205199 const unacknowledgedWrite = this . writeConcern ?. w === 0 ;
206- if ( unacknowledgedWrite || maxWireVersion ( server ) < 8 ) {
200+ if ( unacknowledgedWrite || maxWireVersion ( connection ) < 8 ) {
207201 throw new MongoCompatibilityError (
208202 'The current topology does not support a hint on findAndModify commands'
209203 ) ;
210204 }
211205
212- cmd . hint = options . hint ;
206+ command . hint = options . hint ;
213207 }
214208
215- // Execute the command
216- const result = await super . executeCommand ( server , session , cmd , timeoutContext ) ;
217- return options . includeResultMetadata ? result : ( result . value ?? null ) ;
209+ return command ;
210+ }
211+
212+ override handleOk ( response : InstanceType < typeof this . SERVER_COMMAND_RESPONSE_TYPE > ) : Document {
213+ const result = super . handleOk ( response ) ;
214+ return this . options . includeResultMetadata ? result : ( result . value ?? null ) ;
218215 }
219216}
220217
@@ -227,12 +224,21 @@ export class FindOneAndDeleteOperation extends FindAndModifyOperation {
227224 }
228225
229226 super ( collection , filter , options ) ;
230- this . cmdBase . remove = true ;
227+ }
228+
229+ override buildCommandDocument (
230+ connection : Connection ,
231+ session ?: ClientSession
232+ ) : FindAndModifyCmdBase {
233+ const command = super . buildCommandDocument ( connection , session ) ;
234+ command . remove = true ;
235+ return command ;
231236 }
232237}
233238
234239/** @internal */
235240export class FindOneAndReplaceOperation extends FindAndModifyOperation {
241+ private replacement : Document ;
236242 constructor (
237243 collection : Collection ,
238244 filter : Document ,
@@ -250,15 +256,27 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
250256 if ( hasAtomicOperators ( replacement ) ) {
251257 throw new MongoInvalidArgumentError ( 'Replacement document must not contain atomic operators' ) ;
252258 }
253-
254259 super ( collection , filter , options ) ;
255- this . cmdBase . update = replacement ;
256- configureFindAndModifyCmdBaseUpdateOpts ( this . cmdBase , options ) ;
260+
261+ this . replacement = replacement ;
262+ }
263+
264+ override buildCommandDocument (
265+ connection : Connection ,
266+ session ?: ClientSession
267+ ) : FindAndModifyCmdBase {
268+ const command = super . buildCommandDocument ( connection , session ) ;
269+ command . update = this . replacement ;
270+ configureFindAndModifyCmdBaseUpdateOpts ( command , this . options ) ;
271+ return command ;
257272 }
258273}
259274
260275/** @internal */
261276export class FindOneAndUpdateOperation extends FindAndModifyOperation {
277+ private update : Document ;
278+ override options : FindOneAndUpdateOptions ;
279+
262280 constructor (
263281 collection : Collection ,
264282 filter : Document ,
@@ -278,12 +296,21 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
278296 }
279297
280298 super ( collection , filter , options ) ;
281- this . cmdBase . update = update ;
282- configureFindAndModifyCmdBaseUpdateOpts ( this . cmdBase , options ) ;
299+ this . update = update ;
300+ this . options = options ;
301+ }
283302
284- if ( options . arrayFilters ) {
285- this . cmdBase . arrayFilters = options . arrayFilters ;
303+ override buildCommandDocument (
304+ connection : Connection ,
305+ session ?: ClientSession
306+ ) : FindAndModifyCmdBase {
307+ const command = super . buildCommandDocument ( connection , session ) ;
308+ command . update = this . update ;
309+ configureFindAndModifyCmdBaseUpdateOpts ( command , this . options ) ;
310+ if ( this . options . arrayFilters ) {
311+ command . arrayFilters = this . options . arrayFilters ;
286312 }
313+ return command ;
287314 }
288315}
289316
0 commit comments