-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
Copy pathoverride_helpers.js
124 lines (105 loc) · 4.77 KB
/
override_helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import {getCommandName} from "jstests/libs/cmd_object_utils.js";
// Store the original 'runCommand' function before applying any overrides.
const preOverrideRunCommand = Mongo.prototype.runCommand;
/**
* The OverrideHelpers object defines convenience methods for overriding commands and functions in
* the mongo shell.
*/
export const OverrideHelpers = (function() {
function makeIsAggregationWithFirstStage(stageName) {
return function(commandName, commandObj) {
if (commandName !== "aggregate" || typeof commandObj !== "object" ||
commandObj === null) {
return false;
}
if (!Array.isArray(commandObj.pipeline) || commandObj.pipeline.length === 0) {
return false;
}
const firstStage = commandObj.pipeline[0];
if (typeof firstStage !== "object" || firstStage === null) {
return false;
}
return Object.keys(firstStage)[0] === stageName;
};
}
function isAggregationWithOutOrMergeStage(commandName, commandObj) {
if (commandName !== "aggregate" || typeof commandObj !== "object" || commandObj === null) {
return false;
}
if (!Array.isArray(commandObj.pipeline) || commandObj.pipeline.length === 0) {
return false;
}
const lastStage = commandObj.pipeline[commandObj.pipeline.length - 1];
if (typeof lastStage !== "object" || lastStage === null) {
return false;
}
const lastStageName = Object.keys(lastStage)[0];
return lastStageName === "$out" || lastStageName === "$merge";
}
function isMapReduceWithInlineOutput(commandName, commandObj) {
if ((commandName !== "mapReduce" && commandName !== "mapreduce") ||
typeof commandObj !== "object" || commandObj === null) {
return false;
}
if (typeof commandObj.out !== "object") {
return false;
}
return commandObj.out.hasOwnProperty("inline");
}
function prependOverrideInParallelShell(overrideFile) {
const startParallelShellOriginal = startParallelShell;
startParallelShell = function(jsCode, port, noConnect) {
let newCode;
if (typeof jsCode === "function") {
// Load the override file and immediately invoke the supplied function.
if (jsCode.constructor.name === 'AsyncFunction') {
newCode = `await import("${overrideFile}"); await (${jsCode.toString()})();`;
} else {
newCode = `await import("${overrideFile}"); (${jsCode.toString()})();`;
}
} else {
newCode = `await import("${overrideFile}"); ${jsCode};`;
}
return startParallelShellOriginal(newCode, port, noConnect);
};
}
function overrideRunCommand(overrideFunc) {
const mongoRunCommandOriginal = Mongo.prototype.runCommand;
Mongo.prototype.runCommand = function(dbName, commandObj, options) {
return overrideFunc(this,
dbName,
getCommandName(commandObj),
commandObj,
mongoRunCommandOriginal,
(commandObj, db = dbName) => [db, commandObj, options]);
};
}
/**
* Higher order function for executing `db.runCommand()` commands without overrides.
* Example usage:
* const res = OverrideHelpers.withPreOverrideRunCommand(() => db.adminCommand(cmd));
*/
function withPreOverrideRunCommand(fn) {
const overriddenRunCommand = Mongo.prototype.runCommand;
try {
Mongo.prototype.runCommand = preOverrideRunCommand;
return fn();
} finally {
Mongo.prototype.runCommand = overriddenRunCommand;
}
}
return {
isAggregationWithListLocalSessionsStage:
makeIsAggregationWithFirstStage("$listLocalSessions"),
isAggregationWithOutOrMergeStage: isAggregationWithOutOrMergeStage,
isAggregationWithCurrentOpStage: makeIsAggregationWithFirstStage("$currentOp"),
isAggregationWithChangeStreamStage: makeIsAggregationWithFirstStage("$changeStream"),
isAggregationWithInternalListCollections:
makeIsAggregationWithFirstStage("$_internalListCollections"),
isAggregationWithListClusterCatalog: makeIsAggregationWithFirstStage("$listClusterCatalog"),
isMapReduceWithInlineOutput: isMapReduceWithInlineOutput,
prependOverrideInParallelShell: prependOverrideInParallelShell,
overrideRunCommand: overrideRunCommand,
withPreOverrideRunCommand: withPreOverrideRunCommand,
};
})();