1
1
import { defineAspects , Aspect , OperationBase , Hint } from './operation' ;
2
- import { removeDocuments } from './common_functions' ;
3
2
import { CommandOperation , CommandOperationOptions } from './command' ;
4
3
import { isObject } from 'util' ;
5
- import type { Callback , MongoDBNamespace } from '../utils' ;
4
+ import {
5
+ applyRetryableWrites ,
6
+ Callback ,
7
+ decorateWithCollation ,
8
+ maxWireVersion ,
9
+ MongoDBNamespace
10
+ } from '../utils' ;
6
11
import type { Document } from '../bson' ;
7
12
import type { Server } from '../sdam/server' ;
8
13
import type { Collection } from '../collection' ;
9
14
import type { WriteCommandOptions } from '../cmap/wire_protocol/write_command' ;
10
- import type { Connection } from '../cmap/connection ' ;
15
+ import { MongoError } from '../error ' ;
11
16
12
17
/** @public */
13
18
export interface DeleteOptions extends CommandOperationOptions {
@@ -17,14 +22,10 @@ export interface DeleteOptions extends CommandOperationOptions {
17
22
18
23
/** @public */
19
24
export interface DeleteResult {
20
- /** Indicates whether this write result was acknowledged */
25
+ /** Indicates whether this write result was acknowledged. If not, then all other members of this result will be undefined. */
21
26
acknowledged : boolean ;
22
27
/** The number of documents that were deleted */
23
28
deletedCount : number ;
24
- /** The raw result returned from MongoDB. Will vary depending on server version */
25
- result : Document ;
26
- /** The connection object used for the operation */
27
- connection ?: Connection ;
28
29
}
29
30
30
31
/** @internal */
@@ -68,15 +69,13 @@ export class DeleteOneOperation extends CommandOperation<DeleteOptions, DeleteRe
68
69
const options = { ...this . options , ...this . bsonOptions } ;
69
70
70
71
options . single = true ;
71
- removeDocuments ( server , coll , filter , options , ( err , r ) => {
72
- if ( callback == null ) return ;
73
- if ( err && callback ) return callback ( err ) ;
74
- if ( r == null ) {
75
- return callback ( undefined , { acknowledged : true , deletedCount : 0 , result : { ok : 1 } } ) ;
76
- }
77
-
78
- r . deletedCount = r . n ;
79
- if ( callback ) callback ( undefined , r ) ;
72
+ removeDocuments ( server , coll , filter , options , ( err , res ) => {
73
+ if ( err || res == null ) return callback ( err ) ;
74
+ if ( typeof options . explain !== 'undefined' ) return callback ( undefined , res ) ;
75
+ callback ( undefined , {
76
+ acknowledged : this . writeConcern ?. w !== 0 ?? true ,
77
+ deletedCount : res . n
78
+ } ) ;
80
79
} ) ;
81
80
}
82
81
}
@@ -106,19 +105,84 @@ export class DeleteManyOperation extends CommandOperation<DeleteOptions, DeleteR
106
105
options . single = false ;
107
106
}
108
107
109
- removeDocuments ( server , coll , filter , options , ( err , r ) => {
110
- if ( callback == null ) return ;
111
- if ( err && callback ) return callback ( err ) ;
112
- if ( r == null ) {
113
- return callback ( undefined , { acknowledged : true , deletedCount : 0 , result : { ok : 1 } } ) ;
114
- }
115
-
116
- r . deletedCount = r . n ;
117
- if ( callback ) callback ( undefined , r ) ;
108
+ removeDocuments ( server , coll , filter , options , ( err , res ) => {
109
+ if ( err || res == null ) return callback ( err ) ;
110
+ if ( typeof options . explain !== 'undefined' ) return callback ( undefined , res ) ;
111
+ callback ( undefined , {
112
+ acknowledged : this . writeConcern ?. w !== 0 ?? true ,
113
+ deletedCount : res . n
114
+ } ) ;
118
115
} ) ;
119
116
}
120
117
}
121
118
119
+ function removeDocuments (
120
+ server : Server ,
121
+ coll : Collection ,
122
+ selector : Document ,
123
+ options : DeleteOptions | Document ,
124
+ callback : Callback
125
+ ) : void {
126
+ if ( typeof options === 'function' ) {
127
+ ( callback = options as Callback ) , ( options = { } ) ;
128
+ } else if ( typeof selector === 'function' ) {
129
+ callback = selector as Callback ;
130
+ options = { } ;
131
+ selector = { } ;
132
+ }
133
+
134
+ // Create an empty options object if the provided one is null
135
+ options = options || { } ;
136
+
137
+ // Final options for retryable writes
138
+ let finalOptions = Object . assign ( { } , options ) ;
139
+ finalOptions = applyRetryableWrites ( finalOptions , coll . s . db ) ;
140
+
141
+ // If selector is null set empty
142
+ if ( selector == null ) selector = { } ;
143
+
144
+ // Build the op
145
+ const op = { q : selector , limit : 0 } as any ;
146
+ if ( options . single ) {
147
+ op . limit = 1 ;
148
+ } else if ( finalOptions . retryWrites ) {
149
+ finalOptions . retryWrites = false ;
150
+ }
151
+ if ( options . hint ) {
152
+ op . hint = options . hint ;
153
+ }
154
+
155
+ // Have we specified collation
156
+ try {
157
+ decorateWithCollation ( finalOptions , coll , options ) ;
158
+ } catch ( err ) {
159
+ return callback ? callback ( err , null ) : undefined ;
160
+ }
161
+
162
+ if ( options . explain !== undefined && maxWireVersion ( server ) < 3 ) {
163
+ return callback
164
+ ? callback ( new MongoError ( `server ${ server . name } does not support explain on remove` ) )
165
+ : undefined ;
166
+ }
167
+
168
+ // Execute the remove
169
+ server . remove (
170
+ coll . s . namespace . toString ( ) ,
171
+ [ op ] ,
172
+ finalOptions as WriteCommandOptions ,
173
+ ( err , result ) => {
174
+ if ( err || result == null ) return callback ( err ) ;
175
+ if ( result . code ) return callback ( new MongoError ( result ) ) ;
176
+ if ( result . writeErrors ) {
177
+ return callback ( new MongoError ( result . writeErrors [ 0 ] ) ) ;
178
+ }
179
+
180
+ // Return the results
181
+ callback ( undefined , result ) ;
182
+ }
183
+ ) ;
184
+ }
185
+
122
186
defineAspects ( DeleteOperation , [ Aspect . RETRYABLE , Aspect . WRITE_OPERATION ] ) ;
123
187
defineAspects ( DeleteOneOperation , [ Aspect . RETRYABLE , Aspect . WRITE_OPERATION , Aspect . EXPLAINABLE ] ) ;
124
188
defineAspects ( DeleteManyOperation , [ Aspect . WRITE_OPERATION , Aspect . EXPLAINABLE ] ) ;
0 commit comments