1
+ import { type Connection } from '..' ;
1
2
import type { Document } from '../bson' ;
3
+ import { MongoDBResponse } from '../cmap/wire_protocol/responses' ;
2
4
import type { Collection } from '../collection' ;
3
5
import { MongoCompatibilityError , MongoInvalidArgumentError } from '../error' ;
4
6
import { ReadPreference } from '../read_preference' ;
5
- import type { Server } from '../sdam/server' ;
6
7
import type { ClientSession } from '../sessions' ;
7
8
import { 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' ;
10
10
import { type WriteConcern , type WriteConcernSettings } from '../write_concern' ;
11
- import { CommandOperation , type CommandOperationOptions } from './command' ;
11
+ import { type CommandOperationOptions , ModernizedCommandOperation } from './command' ;
12
12
import { Aspect , defineAspects } from './operation' ;
13
13
14
14
/** @public */
@@ -120,12 +120,12 @@ function configureFindAndModifyCmdBaseUpdateOpts(
120
120
}
121
121
122
122
/** @internal */
123
- export class FindAndModifyOperation extends CommandOperation < Document > {
123
+ export class FindAndModifyOperation extends ModernizedCommandOperation < Document > {
124
+ override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse ;
125
+
124
126
override options : FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions ;
125
- cmdBase : FindAndModifyCmdBase ;
126
127
collection : Collection ;
127
128
query : Document ;
128
- doc ?: Document ;
129
129
130
130
constructor (
131
131
collection : Collection ,
@@ -134,87 +134,84 @@ export class FindAndModifyOperation extends CommandOperation<Document> {
134
134
) {
135
135
super ( collection , options ) ;
136
136
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 ,
138
163
remove : false ,
139
164
new : false ,
140
165
upsert : false
141
166
} ;
142
167
143
- options . includeResultMetadata ??= false ;
144
-
145
168
const sort = formatSort ( options . sort ) ;
146
169
if ( sort ) {
147
- this . cmdBase . sort = sort ;
170
+ command . sort = sort ;
148
171
}
149
172
150
173
if ( options . projection ) {
151
- this . cmdBase . fields = options . projection ;
174
+ command . fields = options . projection ;
152
175
}
153
176
154
177
if ( options . maxTimeMS ) {
155
- this . cmdBase . maxTimeMS = options . maxTimeMS ;
178
+ command . maxTimeMS = options . maxTimeMS ;
156
179
}
157
180
158
181
// Decorate the findAndModify command with the write Concern
159
182
if ( options . writeConcern ) {
160
- this . cmdBase . writeConcern = options . writeConcern ;
183
+ command . writeConcern = options . writeConcern ;
161
184
}
162
185
163
186
if ( options . let ) {
164
- this . cmdBase . let = options . let ;
187
+ command . let = options . let ;
165
188
}
166
189
167
190
// we check for undefined specifically here to allow falsy values
168
191
// eslint-disable-next-line no-restricted-syntax
169
192
if ( options . comment !== undefined ) {
170
- this . cmdBase . comment = options . comment ;
193
+ command . comment = options . comment ;
171
194
}
172
195
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
-
202
196
if ( options . hint ) {
203
197
// TODO: once this method becomes a CommandOperation we will have the server
204
198
// in place to check.
205
199
const unacknowledgedWrite = this . writeConcern ?. w === 0 ;
206
- if ( unacknowledgedWrite || maxWireVersion ( server ) < 8 ) {
200
+ if ( unacknowledgedWrite || maxWireVersion ( connection ) < 8 ) {
207
201
throw new MongoCompatibilityError (
208
202
'The current topology does not support a hint on findAndModify commands'
209
203
) ;
210
204
}
211
205
212
- cmd . hint = options . hint ;
206
+ command . hint = options . hint ;
213
207
}
214
208
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 ) ;
218
215
}
219
216
}
220
217
@@ -227,12 +224,21 @@ export class FindOneAndDeleteOperation extends FindAndModifyOperation {
227
224
}
228
225
229
226
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 ;
231
236
}
232
237
}
233
238
234
239
/** @internal */
235
240
export class FindOneAndReplaceOperation extends FindAndModifyOperation {
241
+ private replacement : Document ;
236
242
constructor (
237
243
collection : Collection ,
238
244
filter : Document ,
@@ -250,15 +256,27 @@ export class FindOneAndReplaceOperation extends FindAndModifyOperation {
250
256
if ( hasAtomicOperators ( replacement ) ) {
251
257
throw new MongoInvalidArgumentError ( 'Replacement document must not contain atomic operators' ) ;
252
258
}
253
-
254
259
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 ;
257
272
}
258
273
}
259
274
260
275
/** @internal */
261
276
export class FindOneAndUpdateOperation extends FindAndModifyOperation {
277
+ private update : Document ;
278
+ override options : FindOneAndUpdateOptions ;
279
+
262
280
constructor (
263
281
collection : Collection ,
264
282
filter : Document ,
@@ -278,12 +296,21 @@ export class FindOneAndUpdateOperation extends FindAndModifyOperation {
278
296
}
279
297
280
298
super ( collection , filter , options ) ;
281
- this . cmdBase . update = update ;
282
- configureFindAndModifyCmdBaseUpdateOpts ( this . cmdBase , options ) ;
299
+ this . update = update ;
300
+ this . options = options ;
301
+ }
283
302
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 ;
286
312
}
313
+ return command ;
287
314
}
288
315
}
289
316
0 commit comments