Skip to content

Commit 8c5ace7

Browse files
committed
check explain supported in individual op classes
1 parent 001ec2e commit 8c5ace7

File tree

9 files changed

+37
-47
lines changed

9 files changed

+37
-47
lines changed

src/cmap/wire_protocol/write_command.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,9 @@ export function writeCommand(
6767

6868
// If a command is to be explained, we need to reformat the command after
6969
// the other command properties are specified.
70-
if (options.explain !== undefined) {
71-
const explain = Explain.fromOptions(options);
72-
if (explain) {
73-
writeCommand = decorateWithExplain(writeCommand, explain);
74-
}
70+
const explain = Explain.fromOptions(options);
71+
if (explain) {
72+
writeCommand = decorateWithExplain(writeCommand, explain);
7573
}
7674

7775
const commandOptions = Object.assign(

src/explain.ts

-28
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import type { Document } from '.';
21
import { MongoError } from './error';
3-
import type { Server } from './sdam/server';
4-
import { maxWireVersion } from './utils';
52

63
/** @public */
74
export const ExplainVerbosity = {
@@ -24,13 +21,6 @@ export interface ExplainOptions {
2421
explain?: ExplainVerbosityLike;
2522
}
2623

27-
// Minimum server versions which support explain with specific operations
28-
const SUPPORTS_EXPLAIN_WITH_REMOVE = 3;
29-
const SUPPORTS_EXPLAIN_WITH_UPDATE = 3;
30-
const SUPPORTS_EXPLAIN_WITH_DISTINCT = 4;
31-
const SUPPORTS_EXPLAIN_WITH_FIND_AND_MODIFY = 4;
32-
const SUPPORTS_EXPLAIN_WITH_MAP_REDUCE = 9;
33-
3424
/** @internal */
3525
export class Explain {
3626
verbosity: keyof typeof ExplainVerbosity;
@@ -55,22 +45,4 @@ export class Explain {
5545

5646
throw new MongoError(`explain must be one of ${Object.keys(ExplainVerbosity)} or a boolean`);
5747
}
58-
59-
/** Checks that the server supports explain on the given operation or command.*/
60-
static explainSupported(server: Server, op: string | Document): boolean {
61-
const wireVersion = maxWireVersion(server);
62-
if (op === 'remove' || (typeof op === 'object' && op.remove)) {
63-
return wireVersion >= SUPPORTS_EXPLAIN_WITH_REMOVE;
64-
} else if (op === 'update' || (typeof op === 'object' && op.update)) {
65-
return wireVersion >= SUPPORTS_EXPLAIN_WITH_UPDATE;
66-
} else if (op === 'distinct' || (typeof op === 'object' && op.distinct)) {
67-
return wireVersion >= SUPPORTS_EXPLAIN_WITH_DISTINCT;
68-
} else if (op === 'findAndModify' || (typeof op === 'object' && op.findAndModify)) {
69-
return wireVersion >= SUPPORTS_EXPLAIN_WITH_FIND_AND_MODIFY;
70-
} else if (op === 'mapReduce' || (typeof op === 'object' && op.mapReduce)) {
71-
return wireVersion >= SUPPORTS_EXPLAIN_WITH_MAP_REDUCE;
72-
}
73-
74-
return false;
75-
}
7648
}

src/operations/command.ts

-5
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,6 @@ export abstract class CommandOperation<
156156
}
157157

158158
if (this.hasAspect(Aspect.EXPLAINABLE) && this.explain) {
159-
if (!Explain.explainSupported(server, cmd)) {
160-
callback(new MongoError(`server ${server.name} does not support explain on this command`));
161-
return;
162-
}
163-
164159
cmd = decorateWithExplain(cmd, this.explain);
165160
}
166161

src/operations/common_functions.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
applyWriteConcern,
55
decorateWithCollation,
66
Callback,
7-
getTopology
7+
getTopology,
8+
maxWireVersion
89
} from '../utils';
910
import type { Document } from '../bson';
1011
import type { Db } from '../db';
@@ -162,6 +163,12 @@ export function removeDocuments(
162163
return callback ? callback(err, null) : undefined;
163164
}
164165

166+
if (options.explain !== undefined && maxWireVersion(server) < 3) {
167+
return callback
168+
? callback(new MongoError(`server ${server.name} does not support explain on remove`))
169+
: undefined;
170+
}
171+
165172
// Execute the remove
166173
server.remove(
167174
coll.s.namespace.toString(),
@@ -254,6 +261,12 @@ export function updateDocuments(
254261
return callback(err, null);
255262
}
256263

264+
if (options.explain !== undefined && maxWireVersion(server) < 3) {
265+
return callback
266+
? callback(new MongoError(`server ${server.name} does not support explain on update`))
267+
: undefined;
268+
}
269+
257270
// Update options
258271
server.update(
259272
coll.s.namespace.toString(),

src/operations/distinct.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Aspect, defineAspects } from './operation';
22
import { CommandOperation, CommandOperationOptions } from './command';
3-
import { decorateWithCollation, decorateWithReadConcern, Callback } from '../utils';
3+
import { decorateWithCollation, decorateWithReadConcern, Callback, maxWireVersion } from '../utils';
44
import type { Document } from '../bson';
55
import type { Server } from '../sdam/server';
66
import type { Collection } from '../collection';
7+
import { MongoError } from '../error';
78

89
/** @public */
910
export type DistinctOptions = CommandOperationOptions;
@@ -63,6 +64,11 @@ export class DistinctOperation extends CommandOperation<DistinctOptions, Documen
6364
return callback(err);
6465
}
6566

67+
if (this.explain && maxWireVersion(server) < 4) {
68+
callback(new MongoError(`server ${server.name} does not support explain on distinct`));
69+
return;
70+
}
71+
6672
super.executeCommand(server, cmd, (err, result) => {
6773
if (err) {
6874
callback(err);

src/operations/find_and_modify.ts

+5
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ export class FindAndModifyOperation extends CommandOperation<FindAndModifyOption
143143
cmd.hint = options.hint;
144144
}
145145

146+
if (this.explain && maxWireVersion(server) < 4) {
147+
callback(new MongoError(`server ${server.name} does not support explain on findAndModify`));
148+
return;
149+
}
150+
146151
// Execute the command
147152
super.executeCommand(server, cmd, (err, result) => {
148153
if (err) return callback(err);

src/operations/map_reduce.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
decorateWithCollation,
66
decorateWithReadConcern,
77
isObject,
8-
Callback
8+
Callback,
9+
maxWireVersion
910
} from '../utils';
1011
import { ReadPreference, ReadPreferenceMode } from '../read_preference';
1112
import { CommandOperation, CommandOperationOptions } from './command';
@@ -158,6 +159,11 @@ export class MapReduceOperation extends CommandOperation<MapReduceOptions, Docum
158159
return callback(err);
159160
}
160161

162+
if (this.explain && maxWireVersion(server) < 9) {
163+
callback(new MongoError(`server ${server.name} does not support explain on mapReduce`));
164+
return;
165+
}
166+
161167
// Execute command
162168
super.executeCommand(server, mapCommandHash, (err, result) => {
163169
if (err) return callback(err);

src/sdam/server.ts

-5
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,6 @@ function executeWriteOperation(
458458
}
459459
}
460460

461-
if (options.explain !== undefined && !Explain.explainSupported(server, op)) {
462-
callback(new MongoError(`server ${server.name} does not support explain on ${op}`));
463-
return;
464-
}
465-
466461
server.s.pool.withConnection((err, conn, cb) => {
467462
if (err || !conn) {
468463
markServerUnknown(server, err);

src/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ export function decorateWithReadConcern(
447447
* Applies an explain to a given command.
448448
* @internal
449449
*
450-
* @param command - the command on which to apply the read concern
450+
* @param command - the command on which to apply the explain
451451
* @param options - the options containing the explain verbosity
452452
*/
453453
export function decorateWithExplain(command: Document, explain: Explain): Document {

0 commit comments

Comments
 (0)