@@ -7,14 +7,13 @@ import {
7
7
hasAtomicOperators ,
8
8
Callback ,
9
9
MongoDBNamespace ,
10
- maxWireVersion ,
11
10
getTopology ,
12
11
resolveOptions
13
12
} from '../utils' ;
14
13
import { executeOperation } from '../operations/execute_operation' ;
15
14
import { InsertOperation } from '../operations/insert' ;
16
- import { UpdateOperation , UpdateStatement } from '../operations/update' ;
17
- import { DeleteOperation , DeleteStatement } from '../operations/delete' ;
15
+ import { UpdateOperation , UpdateStatement , makeUpdateStatement } from '../operations/update' ;
16
+ import { DeleteOperation , DeleteStatement , makeDeleteStatement } from '../operations/delete' ;
18
17
import { WriteConcern } from '../write_concern' ;
19
18
import type { Collection } from '../collection' ;
20
19
import type { Topology } from '../sdam/topology' ;
@@ -725,63 +724,15 @@ export class FindOperators {
725
724
this . bulkOperation = bulkOperation ;
726
725
}
727
726
728
- /** @internal */
729
- makeUpdateDocument ( u : Document , multi : boolean ) : Document {
730
- if ( ! this . bulkOperation . s . currentOp ) {
731
- this . bulkOperation . s . currentOp = { } ;
732
- }
733
-
734
- // Perform upsert
735
- const upsert =
736
- typeof this . bulkOperation . s . currentOp . upsert === 'boolean'
737
- ? this . bulkOperation . s . currentOp . upsert
738
- : false ;
739
-
740
- // Establish the update command
741
- const q = this . bulkOperation . s . currentOp . selector ;
742
- const result : Document = { q, u, multi, upsert } ;
743
-
744
- if ( u . hint ) {
745
- result . hint = u . hint ;
746
- }
747
-
748
- if ( this . bulkOperation . s . currentOp . collation ) {
749
- result . collation = this . bulkOperation . s . currentOp . collation ;
750
- }
751
-
752
- // Clear out current Op
753
- this . bulkOperation . s . currentOp = undefined ;
754
-
755
- return result ;
756
- }
757
-
758
- /** @internal */
759
- makeDeleteDocument ( limit : number ) : Document {
760
- if ( ! this . bulkOperation . s . currentOp ) {
761
- this . bulkOperation . s . currentOp = { } ;
762
- }
763
-
764
- // Establish the update command
765
- const document : DeleteStatement = {
766
- q : this . bulkOperation . s . currentOp . selector ,
767
- limit
768
- } ;
769
-
770
- if ( this . bulkOperation . s . currentOp . collation ) {
771
- document . collation = this . bulkOperation . s . currentOp . collation ;
772
- }
773
-
774
- // Clear out current Op
775
- this . bulkOperation . s . currentOp = undefined ;
776
-
777
- return document ;
778
- }
779
-
780
727
/** Add a multiple update operation to the bulk operation */
781
728
update ( updateDocument : Document ) : BulkOperationBase {
729
+ const currentOp = buildCurrentOp ( this . bulkOperation ) ;
782
730
return this . bulkOperation . addToOperationsList (
783
731
BatchType . UPDATE ,
784
- this . makeUpdateDocument ( updateDocument , true )
732
+ makeUpdateStatement ( currentOp . selector , updateDocument , {
733
+ ...currentOp ,
734
+ multi : true
735
+ } )
785
736
) ;
786
737
}
787
738
@@ -791,9 +742,10 @@ export class FindOperators {
791
742
throw new TypeError ( 'Update document requires atomic operators' ) ;
792
743
}
793
744
745
+ const currentOp = buildCurrentOp ( this . bulkOperation ) ;
794
746
return this . bulkOperation . addToOperationsList (
795
747
BatchType . UPDATE ,
796
- this . makeUpdateDocument ( updateDocument , false )
748
+ makeUpdateStatement ( currentOp . selector , updateDocument , { ... currentOp , multi : false } )
797
749
) ;
798
750
}
799
751
@@ -803,20 +755,29 @@ export class FindOperators {
803
755
throw new TypeError ( 'Replacement document must not use atomic operators' ) ;
804
756
}
805
757
758
+ const currentOp = buildCurrentOp ( this . bulkOperation ) ;
806
759
return this . bulkOperation . addToOperationsList (
807
760
BatchType . UPDATE ,
808
- this . makeUpdateDocument ( replacement , false )
761
+ makeUpdateStatement ( currentOp . selector , replacement , { ... currentOp , multi : false } )
809
762
) ;
810
763
}
811
764
812
765
/** Add a delete one operation to the bulk operation */
813
766
deleteOne ( ) : BulkOperationBase {
814
- return this . bulkOperation . addToOperationsList ( BatchType . DELETE , this . makeDeleteDocument ( 1 ) ) ;
767
+ const currentOp = buildCurrentOp ( this . bulkOperation ) ;
768
+ return this . bulkOperation . addToOperationsList (
769
+ BatchType . DELETE ,
770
+ makeDeleteStatement ( currentOp . selector , { ...currentOp , limit : 1 } )
771
+ ) ;
815
772
}
816
773
817
774
/** Add a delete many operation to the bulk operation */
818
775
delete ( ) : BulkOperationBase {
819
- return this . bulkOperation . addToOperationsList ( BatchType . DELETE , this . makeDeleteDocument ( 0 ) ) ;
776
+ const currentOp = buildCurrentOp ( this . bulkOperation ) ;
777
+ return this . bulkOperation . addToOperationsList (
778
+ BatchType . DELETE ,
779
+ makeDeleteStatement ( currentOp . selector , { ...currentOp , limit : 0 } )
780
+ ) ;
820
781
}
821
782
822
783
removeOne ( ) : BulkOperationBase {
@@ -1111,19 +1072,23 @@ export abstract class BulkOperationBase {
1111
1072
1112
1073
if ( 'replaceOne' in op || 'updateOne' in op || 'updateMany' in op ) {
1113
1074
if ( 'replaceOne' in op ) {
1114
- const updateStatement = makeUpdateStatement ( this . s . topology , op . replaceOne , false ) ;
1075
+ const updateStatement = makeUpdateStatement (
1076
+ op . replaceOne . filter ,
1077
+ op . replaceOne . replacement ,
1078
+ { ...op . replaceOne , multi : false }
1079
+ ) ;
1115
1080
if ( hasAtomicOperators ( updateStatement . u ) ) {
1116
1081
throw new TypeError ( 'Replacement document must not use atomic operators' ) ;
1117
1082
}
1118
1083
1119
- return this . addToOperationsList (
1120
- BatchType . UPDATE ,
1121
- makeUpdateStatement ( this . s . topology , op . replaceOne , false )
1122
- ) ;
1084
+ return this . addToOperationsList ( BatchType . UPDATE , updateStatement ) ;
1123
1085
}
1124
1086
1125
1087
if ( 'updateOne' in op ) {
1126
- const updateStatement = makeUpdateStatement ( this . s . topology , op . updateOne , false ) ;
1088
+ const updateStatement = makeUpdateStatement ( op . updateOne . filter , op . updateOne . update , {
1089
+ ...op . updateOne ,
1090
+ multi : false
1091
+ } ) ;
1127
1092
if ( ! hasAtomicOperators ( updateStatement . u ) ) {
1128
1093
throw new TypeError ( 'Update document requires atomic operators' ) ;
1129
1094
}
@@ -1132,7 +1097,10 @@ export abstract class BulkOperationBase {
1132
1097
}
1133
1098
1134
1099
if ( 'updateMany' in op ) {
1135
- const updateStatement = makeUpdateStatement ( this . s . topology , op . updateMany , true ) ;
1100
+ const updateStatement = makeUpdateStatement ( op . updateMany . filter , op . updateMany . update , {
1101
+ ...op . updateMany ,
1102
+ multi : true
1103
+ } ) ;
1136
1104
if ( ! hasAtomicOperators ( updateStatement . u ) ) {
1137
1105
throw new TypeError ( 'Update document requires atomic operators' ) ;
1138
1106
}
@@ -1144,28 +1112,28 @@ export abstract class BulkOperationBase {
1144
1112
if ( 'removeOne' in op ) {
1145
1113
return this . addToOperationsList (
1146
1114
BatchType . DELETE ,
1147
- makeDeleteStatement ( this . s . topology , op . removeOne , false )
1115
+ makeDeleteStatement ( op . removeOne . filter , { ... op . removeOne , limit : 1 } )
1148
1116
) ;
1149
1117
}
1150
1118
1151
1119
if ( 'removeMany' in op ) {
1152
1120
return this . addToOperationsList (
1153
1121
BatchType . DELETE ,
1154
- makeDeleteStatement ( this . s . topology , op . removeMany , true )
1122
+ makeDeleteStatement ( op . removeMany . filter , { ... op . removeMany , limit : 0 } )
1155
1123
) ;
1156
1124
}
1157
1125
1158
1126
if ( 'deleteOne' in op ) {
1159
1127
return this . addToOperationsList (
1160
1128
BatchType . DELETE ,
1161
- makeDeleteStatement ( this . s . topology , op . deleteOne , false )
1129
+ makeDeleteStatement ( op . deleteOne . filter , { ... op . deleteOne , limit : 1 } )
1162
1130
) ;
1163
1131
}
1164
1132
1165
1133
if ( 'deleteMany' in op ) {
1166
1134
return this . addToOperationsList (
1167
1135
BatchType . DELETE ,
1168
- makeDeleteStatement ( this . s . topology , op . deleteMany , true )
1136
+ makeDeleteStatement ( op . deleteMany . filter , { ... op . deleteMany , limit : 0 } )
1169
1137
) ;
1170
1138
}
1171
1139
@@ -1303,94 +1271,6 @@ function shouldForceServerObjectId(bulkOperation: BulkOperationBase): boolean {
1303
1271
return false ;
1304
1272
}
1305
1273
1306
- function makeUpdateStatement (
1307
- topology : Topology ,
1308
- model : ReplaceOneModel | UpdateOneModel | UpdateManyModel ,
1309
- multi : boolean
1310
- ) : UpdateStatement {
1311
- // NOTE: legacy support for a raw statement, consider removing
1312
- if ( isUpdateStatement ( model ) ) {
1313
- if ( 'collation' in model && maxWireVersion ( topology ) < 5 ) {
1314
- throw new TypeError ( 'Topology does not support collation' ) ;
1315
- }
1316
-
1317
- return model as UpdateStatement ;
1318
- }
1319
-
1320
- const statement : UpdateStatement = {
1321
- q : model . filter ,
1322
- u : 'update' in model ? model . update : model . replacement ,
1323
- multi,
1324
- upsert : 'upsert' in model ? model . upsert : false
1325
- } ;
1326
-
1327
- if ( 'collation' in model ) {
1328
- if ( maxWireVersion ( topology ) < 5 ) {
1329
- throw new TypeError ( 'Topology does not support collation' ) ;
1330
- }
1331
-
1332
- statement . collation = model . collation ;
1333
- }
1334
-
1335
- if ( 'arrayFilters' in model ) {
1336
- // TODO: this check should be done at command construction against a connection, not a topology
1337
- if ( maxWireVersion ( topology ) < 6 ) {
1338
- throw new TypeError ( 'arrayFilters are only supported on MongoDB 3.6+' ) ;
1339
- }
1340
-
1341
- statement . arrayFilters = model . arrayFilters ;
1342
- }
1343
-
1344
- if ( 'hint' in model ) {
1345
- statement . hint = model . hint ;
1346
- }
1347
-
1348
- return statement ;
1349
- }
1350
-
1351
- function isUpdateStatement ( model : Document ) : model is UpdateStatement {
1352
- return 'q' in model ;
1353
- }
1354
-
1355
- function makeDeleteStatement (
1356
- topology : Topology ,
1357
- model : DeleteOneModel | DeleteManyModel ,
1358
- multi : boolean
1359
- ) : DeleteStatement {
1360
- // NOTE: legacy support for a raw statement, consider removing
1361
- if ( isDeleteStatement ( model ) ) {
1362
- if ( 'collation' in model && maxWireVersion ( topology ) < 5 ) {
1363
- throw new TypeError ( 'Topology does not support collation' ) ;
1364
- }
1365
-
1366
- model . limit = multi ? 0 : 1 ;
1367
- return model as DeleteStatement ;
1368
- }
1369
-
1370
- const statement : DeleteStatement = {
1371
- q : model . filter ,
1372
- limit : multi ? 0 : 1
1373
- } ;
1374
-
1375
- if ( 'collation' in model ) {
1376
- if ( maxWireVersion ( topology ) < 5 ) {
1377
- throw new TypeError ( 'Topology does not support collation' ) ;
1378
- }
1379
-
1380
- statement . collation = model . collation ;
1381
- }
1382
-
1383
- if ( 'hint' in model ) {
1384
- statement . hint = model . hint ;
1385
- }
1386
-
1387
- return statement ;
1388
- }
1389
-
1390
- function isDeleteStatement ( model : Document ) : model is DeleteStatement {
1391
- return 'q' in model ;
1392
- }
1393
-
1394
1274
function isInsertBatch ( batch : Batch ) : boolean {
1395
1275
return batch . batchType === BatchType . INSERT ;
1396
1276
}
@@ -1402,3 +1282,10 @@ function isUpdateBatch(batch: Batch): batch is Batch<UpdateStatement> {
1402
1282
function isDeleteBatch ( batch : Batch ) : batch is Batch < DeleteStatement > {
1403
1283
return batch . batchType === BatchType . DELETE ;
1404
1284
}
1285
+
1286
+ function buildCurrentOp ( bulkOp : BulkOperationBase ) : Document {
1287
+ let { currentOp } = bulkOp . s ;
1288
+ bulkOp . s . currentOp = undefined ;
1289
+ if ( ! currentOp ) currentOp = { } ;
1290
+ return currentOp ;
1291
+ }
0 commit comments