mongodb 3.0.4 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +2 -1
- package/CHANGES_3.0.0.md +28 -0
- package/CODE_OF_CONDUCT.md +80 -0
- package/CONTRIBUTING.md +29 -0
- package/HISTORY.md +52 -0
- package/conf.json +0 -1
- package/index.js +6 -4
- package/lib/admin.js +6 -49
- package/lib/aggregation_cursor.js +7 -46
- package/lib/apm.js +21 -629
- package/lib/bulk/common.js +0 -23
- package/lib/bulk/ordered.js +15 -22
- package/lib/bulk/unordered.js +15 -22
- package/lib/collection.js +60 -182
- package/lib/command_cursor.js +11 -34
- package/lib/cursor.js +48 -90
- package/lib/db.js +55 -124
- package/lib/gridfs/grid_store.js +12 -61
- package/lib/mongo_client.js +37 -31
- package/lib/topologies/mongos.js +47 -41
- package/lib/topologies/replset.js +46 -39
- package/lib/topologies/server.js +46 -40
- package/lib/topologies/topology_base.js +2 -4
- package/lib/url_parser.js +10 -0
- package/lib/utils.js +52 -5
- package/package.json +5 -5
- package/lib/metadata.js +0 -70
- package/yarn.lock +0 -3904
package/lib/apm.js
CHANGED
|
@@ -1,639 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
const EventEmitter = require('events').EventEmitter;
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// Get prototypes
|
|
7
|
-
var AggregationCursor = require('./aggregation_cursor'),
|
|
8
|
-
CommandCursor = require('./command_cursor'),
|
|
9
|
-
OrderedBulkOperation = require('./bulk/ordered').OrderedBulkOperation,
|
|
10
|
-
UnorderedBulkOperation = require('./bulk/unordered').UnorderedBulkOperation,
|
|
11
|
-
GridStore = require('./gridfs/grid_store'),
|
|
12
|
-
Cursor = require('./cursor'),
|
|
13
|
-
Collection = require('./collection'),
|
|
14
|
-
Db = require('./db');
|
|
15
|
-
|
|
16
|
-
var basicOperationIdGenerator = {
|
|
17
|
-
operationId: 1,
|
|
18
|
-
|
|
19
|
-
next: function() {
|
|
20
|
-
return this.operationId++;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
var basicTimestampGenerator = {
|
|
25
|
-
current: function() {
|
|
26
|
-
return new Date().getTime();
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
duration: function(start, end) {
|
|
30
|
-
return end - start;
|
|
4
|
+
class Instrumentation extends EventEmitter {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
31
7
|
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
var senstiveCommands = [
|
|
35
|
-
'authenticate',
|
|
36
|
-
'saslStart',
|
|
37
|
-
'saslContinue',
|
|
38
|
-
'getnonce',
|
|
39
|
-
'createUser',
|
|
40
|
-
'updateUser',
|
|
41
|
-
'copydbgetnonce',
|
|
42
|
-
'copydbsaslstart',
|
|
43
|
-
'copydb'
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
var Instrumentation = function(core, options, callback) {
|
|
47
|
-
options = options || {};
|
|
48
|
-
|
|
49
|
-
// Optional id generators
|
|
50
|
-
var operationIdGenerator = options.operationIdGenerator || basicOperationIdGenerator;
|
|
51
|
-
// Optional timestamp generator
|
|
52
|
-
var timestampGenerator = options.timestampGenerator || basicTimestampGenerator;
|
|
53
|
-
// Extend with event emitter functionality
|
|
54
|
-
EventEmitter.call(this);
|
|
55
|
-
|
|
56
|
-
// Contains all the instrumentation overloads
|
|
57
|
-
this.overloads = [];
|
|
58
|
-
|
|
59
|
-
// ---------------------------------------------------------
|
|
60
|
-
//
|
|
61
|
-
// Instrument prototype
|
|
62
|
-
//
|
|
63
|
-
// ---------------------------------------------------------
|
|
64
|
-
|
|
65
|
-
var instrumentPrototype = function(callback) {
|
|
66
|
-
var instrumentations = [];
|
|
67
|
-
|
|
68
|
-
// Classes to support
|
|
69
|
-
var classes = [
|
|
70
|
-
GridStore,
|
|
71
|
-
OrderedBulkOperation,
|
|
72
|
-
UnorderedBulkOperation,
|
|
73
|
-
CommandCursor,
|
|
74
|
-
AggregationCursor,
|
|
75
|
-
Cursor,
|
|
76
|
-
Collection,
|
|
77
|
-
Db
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
// Add instrumentations to the available list
|
|
81
|
-
for (var i = 0; i < classes.length; i++) {
|
|
82
|
-
if (classes[i].define) {
|
|
83
|
-
instrumentations.push(classes[i].define.generate());
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Return the list of instrumentation points
|
|
88
|
-
callback(null, instrumentations);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Did the user want to instrument the prototype
|
|
92
|
-
if (typeof callback === 'function') {
|
|
93
|
-
instrumentPrototype(callback);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// ---------------------------------------------------------
|
|
97
|
-
//
|
|
98
|
-
// Server
|
|
99
|
-
//
|
|
100
|
-
// ---------------------------------------------------------
|
|
101
|
-
|
|
102
|
-
// Reference
|
|
103
|
-
var self = this;
|
|
104
|
-
// Names of methods we need to wrap
|
|
105
|
-
var methods = ['command', 'insert', 'update', 'remove'];
|
|
106
|
-
// Prototype
|
|
107
|
-
var proto = core.Server.prototype;
|
|
108
|
-
// Core server method we are going to wrap
|
|
109
|
-
methods.forEach(function(x) {
|
|
110
|
-
var func = proto[x];
|
|
111
|
-
|
|
112
|
-
// Add to overloaded methods
|
|
113
|
-
self.overloads.push({ proto: proto, name: x, func: func });
|
|
114
|
-
|
|
115
|
-
// The actual prototype
|
|
116
|
-
proto[x] = function() {
|
|
117
|
-
var requestId = core.Query.nextRequestId();
|
|
118
|
-
// Get the aruments
|
|
119
|
-
var args = Array.prototype.slice.call(arguments, 0);
|
|
120
|
-
var ns = args[0];
|
|
121
|
-
var commandObj = args[1];
|
|
122
|
-
var options = args[2] || {};
|
|
123
|
-
var keys = Object.keys(commandObj);
|
|
124
|
-
var commandName = keys[0];
|
|
125
|
-
var db = ns.split('.')[0];
|
|
126
|
-
|
|
127
|
-
// Get the collection
|
|
128
|
-
var col = ns.split('.');
|
|
129
|
-
col.shift();
|
|
130
|
-
col = col.join('.');
|
|
131
|
-
|
|
132
|
-
// Do we have a legacy insert/update/remove command
|
|
133
|
-
if (x === 'insert') {
|
|
134
|
-
//} && !this.lastIsMaster().maxWireVersion) {
|
|
135
|
-
commandName = 'insert';
|
|
136
8
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// && !this.lastIsMaster().maxWireVersion) {
|
|
150
|
-
commandName = 'update';
|
|
151
|
-
|
|
152
|
-
// Re-write the command
|
|
153
|
-
commandObj = {
|
|
154
|
-
update: col,
|
|
155
|
-
updates: commandObj
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
if (options.writeConcern && Object.keys(options.writeConcern).length > 0) {
|
|
159
|
-
commandObj.writeConcern = options.writeConcern;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
commandObj.ordered = options.ordered !== undefined ? options.ordered : true;
|
|
163
|
-
} else if (x === 'remove') {
|
|
164
|
-
//&& !this.lastIsMaster().maxWireVersion) {
|
|
165
|
-
commandName = 'delete';
|
|
166
|
-
|
|
167
|
-
// Re-write the command
|
|
168
|
-
commandObj = {
|
|
169
|
-
delete: col,
|
|
170
|
-
deletes: commandObj
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
if (options.writeConcern && Object.keys(options.writeConcern).length > 0) {
|
|
174
|
-
commandObj.writeConcern = options.writeConcern;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
commandObj.ordered = options.ordered !== undefined ? options.ordered : true;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Get the callback
|
|
181
|
-
var callback = args.pop();
|
|
182
|
-
// Set current callback operation id from the current context or create
|
|
183
|
-
// a new one
|
|
184
|
-
var ourOpId = callback.operationId || operationIdGenerator.next();
|
|
185
|
-
|
|
186
|
-
// Get a connection reference for this server instance
|
|
187
|
-
var connection = this.s.pool.get();
|
|
188
|
-
|
|
189
|
-
// Emit the start event for the command
|
|
190
|
-
var command = {
|
|
191
|
-
// Returns the command.
|
|
192
|
-
command: commandObj,
|
|
193
|
-
// Returns the database name.
|
|
194
|
-
databaseName: db,
|
|
195
|
-
// Returns the command name.
|
|
196
|
-
commandName: commandName,
|
|
197
|
-
// Returns the driver generated request id.
|
|
198
|
-
requestId: requestId,
|
|
199
|
-
// Returns the driver generated operation id.
|
|
200
|
-
// This is used to link events together such as bulk write operations. OPTIONAL.
|
|
201
|
-
operationId: ourOpId,
|
|
202
|
-
// Returns the connection id for the command. For languages that do not have this,
|
|
203
|
-
// this MUST return the driver equivalent which MUST include the server address and port.
|
|
204
|
-
// The name of this field is flexible to match the object that is returned from the driver.
|
|
205
|
-
connectionId: connection
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
// Filter out any sensitive commands
|
|
209
|
-
if (senstiveCommands.indexOf(commandName.toLowerCase()) !== -1) {
|
|
210
|
-
command.commandObj = {};
|
|
211
|
-
command.commandObj[commandName] = true;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Emit the started event
|
|
215
|
-
self.emit('started', command);
|
|
216
|
-
|
|
217
|
-
// Start time
|
|
218
|
-
var startTime = timestampGenerator.current();
|
|
219
|
-
|
|
220
|
-
// Push our handler callback
|
|
221
|
-
args.push(function(err, r) {
|
|
222
|
-
var endTime = timestampGenerator.current();
|
|
223
|
-
var command = {
|
|
224
|
-
duration: timestampGenerator.duration(startTime, endTime),
|
|
225
|
-
commandName: commandName,
|
|
226
|
-
requestId: requestId,
|
|
227
|
-
operationId: ourOpId,
|
|
228
|
-
connectionId: connection
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
// If we have an error
|
|
232
|
-
if (err || (r && r.result && r.result.ok === 0)) {
|
|
233
|
-
command.failure = err || r.result.writeErrors || r.result;
|
|
234
|
-
|
|
235
|
-
// Filter out any sensitive commands
|
|
236
|
-
if (senstiveCommands.indexOf(commandName.toLowerCase()) !== -1) {
|
|
237
|
-
command.failure = {};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
self.emit('failed', command);
|
|
241
|
-
} else if (commandObj && commandObj.writeConcern && commandObj.writeConcern.w === 0) {
|
|
242
|
-
// If we have write concern 0
|
|
243
|
-
command.reply = { ok: 1 };
|
|
244
|
-
self.emit('succeeded', command);
|
|
245
|
-
} else {
|
|
246
|
-
command.reply = r && r.result ? r.result : r;
|
|
247
|
-
|
|
248
|
-
// Filter out any sensitive commands
|
|
249
|
-
if (senstiveCommands.indexOf(commandName.toLowerCase()) !== -1) {
|
|
250
|
-
command.reply = {};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
self.emit('succeeded', command);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Return to caller
|
|
257
|
-
callback(err, r);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
// Apply the call
|
|
261
|
-
func.apply(this, args);
|
|
9
|
+
instrument(MongoClient, callback) {
|
|
10
|
+
// store a reference to the original functions
|
|
11
|
+
this.$MongoClient = MongoClient;
|
|
12
|
+
const $prototypeConnect = this.$prototypeConnect = MongoClient.prototype.connect; // eslint-disable-line
|
|
13
|
+
|
|
14
|
+
const instrumentation = this;
|
|
15
|
+
MongoClient.prototype.connect = function(callback) {
|
|
16
|
+
this.s.options.monitorCommands = true;
|
|
17
|
+
this.on('commandStarted', event => instrumentation.emit('started', event));
|
|
18
|
+
this.on('commandSucceeded', event => instrumentation.emit('succeeded', event));
|
|
19
|
+
this.on('commandFailed', event => instrumentation.emit('failed', event));
|
|
20
|
+
return $prototypeConnect.call(this, callback);
|
|
262
21
|
};
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
// ---------------------------------------------------------
|
|
266
|
-
//
|
|
267
|
-
// Bulk Operations
|
|
268
|
-
//
|
|
269
|
-
// ---------------------------------------------------------
|
|
270
22
|
|
|
271
|
-
|
|
272
|
-
methods = ['execute'];
|
|
273
|
-
var prototypes = [
|
|
274
|
-
require('./bulk/ordered').Bulk.prototype,
|
|
275
|
-
require('./bulk/unordered').Bulk.prototype
|
|
276
|
-
];
|
|
277
|
-
|
|
278
|
-
prototypes.forEach(function(proto) {
|
|
279
|
-
// Core server method we are going to wrap
|
|
280
|
-
methods.forEach(function(x) {
|
|
281
|
-
var func = proto[x];
|
|
282
|
-
|
|
283
|
-
// Add to overloaded methods
|
|
284
|
-
self.overloads.push({ proto: proto, name: x, func: func });
|
|
285
|
-
|
|
286
|
-
// The actual prototype
|
|
287
|
-
proto[x] = function() {
|
|
288
|
-
// Get the aruments
|
|
289
|
-
var args = Array.prototype.slice.call(arguments, 0);
|
|
290
|
-
// Set an operation Id on the bulk object
|
|
291
|
-
this.operationId = operationIdGenerator.next();
|
|
292
|
-
|
|
293
|
-
// Get the callback
|
|
294
|
-
var callback = args.pop();
|
|
295
|
-
// If we have a callback use this
|
|
296
|
-
if (typeof callback === 'function') {
|
|
297
|
-
args.push(function(err, r) {
|
|
298
|
-
// Return to caller
|
|
299
|
-
callback(err, r);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
// Apply the call
|
|
303
|
-
func.apply(this, args);
|
|
304
|
-
} else {
|
|
305
|
-
return func.apply(this, args);
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
});
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
// ---------------------------------------------------------
|
|
312
|
-
//
|
|
313
|
-
// Cursor
|
|
314
|
-
//
|
|
315
|
-
// ---------------------------------------------------------
|
|
316
|
-
|
|
317
|
-
// Inject ourselves into the Cursor methods
|
|
318
|
-
methods = ['_find', '_getmore', '_killcursor'];
|
|
319
|
-
prototypes = [
|
|
320
|
-
require('./cursor').prototype,
|
|
321
|
-
require('./command_cursor').prototype,
|
|
322
|
-
require('./aggregation_cursor').prototype
|
|
323
|
-
];
|
|
324
|
-
|
|
325
|
-
// Command name translation
|
|
326
|
-
var commandTranslation = {
|
|
327
|
-
_find: 'find',
|
|
328
|
-
_getmore: 'getMore',
|
|
329
|
-
_killcursor: 'killCursors',
|
|
330
|
-
_explain: 'explain'
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
prototypes.forEach(function(proto) {
|
|
334
|
-
// Core server method we are going to wrap
|
|
335
|
-
methods.forEach(function(x) {
|
|
336
|
-
var func = proto[x];
|
|
337
|
-
|
|
338
|
-
// Add to overloaded methods
|
|
339
|
-
self.overloads.push({ proto: proto, name: x, func: func });
|
|
340
|
-
|
|
341
|
-
// The actual prototype
|
|
342
|
-
proto[x] = function() {
|
|
343
|
-
var cursor = this;
|
|
344
|
-
var requestId = core.Query.nextRequestId();
|
|
345
|
-
var ourOpId = operationIdGenerator.next();
|
|
346
|
-
var parts = this.ns.split('.');
|
|
347
|
-
var db = parts[0];
|
|
348
|
-
|
|
349
|
-
// Get the collection
|
|
350
|
-
parts.shift();
|
|
351
|
-
var collection = parts.join('.');
|
|
352
|
-
|
|
353
|
-
// Set the command
|
|
354
|
-
var command = this.query;
|
|
355
|
-
var cmd = this.s.cmd;
|
|
356
|
-
|
|
357
|
-
// If we have a find method, set the operationId on the cursor
|
|
358
|
-
if (x === '_find') {
|
|
359
|
-
cursor.operationId = ourOpId;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Do we have a find command rewrite it
|
|
363
|
-
if (x === '_getmore') {
|
|
364
|
-
command = {
|
|
365
|
-
getMore: this.cursorState.cursorId,
|
|
366
|
-
collection: collection,
|
|
367
|
-
batchSize: cmd.batchSize
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
if (cmd.maxTimeMS) command.maxTimeMS = cmd.maxTimeMS;
|
|
371
|
-
} else if (x === '_killcursor') {
|
|
372
|
-
command = {
|
|
373
|
-
killCursors: collection,
|
|
374
|
-
cursors: [this.cursorState.cursorId]
|
|
375
|
-
};
|
|
376
|
-
} else if (cmd.find) {
|
|
377
|
-
command = {
|
|
378
|
-
find: collection,
|
|
379
|
-
filter: cmd.query
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
if (cmd.sort) command.sort = cmd.sort;
|
|
383
|
-
if (cmd.fields) command.projection = cmd.fields;
|
|
384
|
-
if (cmd.limit && cmd.limit < 0) {
|
|
385
|
-
command.limit = Math.abs(cmd.limit);
|
|
386
|
-
command.singleBatch = true;
|
|
387
|
-
} else if (cmd.limit) {
|
|
388
|
-
command.limit = Math.abs(cmd.limit);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Options
|
|
392
|
-
if (cmd.skip) command.skip = cmd.skip;
|
|
393
|
-
if (cmd.hint) command.hint = cmd.hint;
|
|
394
|
-
if (cmd.batchSize) command.batchSize = cmd.batchSize;
|
|
395
|
-
if (typeof cmd.returnKey === 'boolean') command.returnKey = cmd.returnKey;
|
|
396
|
-
if (cmd.comment) command.comment = cmd.comment;
|
|
397
|
-
if (cmd.min) command.min = cmd.min;
|
|
398
|
-
if (cmd.max) command.max = cmd.max;
|
|
399
|
-
if (cmd.maxScan) command.maxScan = cmd.maxScan;
|
|
400
|
-
if (cmd.maxTimeMS) command.maxTimeMS = cmd.maxTimeMS;
|
|
401
|
-
|
|
402
|
-
// Flags
|
|
403
|
-
if (typeof cmd.awaitData === 'boolean') command.awaitData = cmd.awaitData;
|
|
404
|
-
if (typeof cmd.snapshot === 'boolean') command.snapshot = cmd.snapshot;
|
|
405
|
-
if (typeof cmd.tailable === 'boolean') command.tailable = cmd.tailable;
|
|
406
|
-
if (typeof cmd.oplogReplay === 'boolean') command.oplogReplay = cmd.oplogReplay;
|
|
407
|
-
if (typeof cmd.noCursorTimeout === 'boolean')
|
|
408
|
-
command.noCursorTimeout = cmd.noCursorTimeout;
|
|
409
|
-
if (typeof cmd.partial === 'boolean') command.partial = cmd.partial;
|
|
410
|
-
if (typeof cmd.showDiskLoc === 'boolean') command.showRecordId = cmd.showDiskLoc;
|
|
411
|
-
|
|
412
|
-
// Read Concern
|
|
413
|
-
if (cmd.readConcern) command.readConcern = cmd.readConcern;
|
|
414
|
-
|
|
415
|
-
// Override method
|
|
416
|
-
if (cmd.explain) command.explain = cmd.explain;
|
|
417
|
-
if (cmd.exhaust) command.exhaust = cmd.exhaust;
|
|
418
|
-
|
|
419
|
-
// If we have a explain flag
|
|
420
|
-
if (cmd.explain) {
|
|
421
|
-
// Create fake explain command
|
|
422
|
-
command = {
|
|
423
|
-
explain: command,
|
|
424
|
-
verbosity: 'allPlansExecution'
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
// Set readConcern on the command if available
|
|
428
|
-
if (cmd.readConcern) command.readConcern = cmd.readConcern;
|
|
429
|
-
|
|
430
|
-
// Set up the _explain name for the command
|
|
431
|
-
x = '_explain';
|
|
432
|
-
}
|
|
433
|
-
} else {
|
|
434
|
-
command = cmd;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Set up the connection
|
|
438
|
-
var connectionId = null;
|
|
439
|
-
|
|
440
|
-
// Set local connection
|
|
441
|
-
if (this.connection) connectionId = this.connection;
|
|
442
|
-
if (!connectionId && this.topology && this.topology.getConnection)
|
|
443
|
-
connectionId = this.topology.getConnection();
|
|
444
|
-
|
|
445
|
-
// Get the command Name
|
|
446
|
-
var commandName = x === '_find' ? Object.keys(command)[0] : commandTranslation[x];
|
|
447
|
-
|
|
448
|
-
// Emit the start event for the command
|
|
449
|
-
command = {
|
|
450
|
-
// Returns the command.
|
|
451
|
-
command: command,
|
|
452
|
-
// Returns the database name.
|
|
453
|
-
databaseName: db,
|
|
454
|
-
// Returns the command name.
|
|
455
|
-
commandName: commandName,
|
|
456
|
-
// Returns the driver generated request id.
|
|
457
|
-
requestId: requestId,
|
|
458
|
-
// Returns the driver generated operation id.
|
|
459
|
-
// This is used to link events together such as bulk write operations. OPTIONAL.
|
|
460
|
-
operationId: this.operationId,
|
|
461
|
-
// Returns the connection id for the command. For languages that do not have this,
|
|
462
|
-
// this MUST return the driver equivalent which MUST include the server address and port.
|
|
463
|
-
// The name of this field is flexible to match the object that is returned from the driver.
|
|
464
|
-
connectionId: connectionId
|
|
465
|
-
};
|
|
466
|
-
|
|
467
|
-
// Get the aruments
|
|
468
|
-
var args = Array.prototype.slice.call(arguments, 0);
|
|
469
|
-
|
|
470
|
-
// Get the callback
|
|
471
|
-
var callback = args.pop();
|
|
472
|
-
|
|
473
|
-
// We do not have a callback but a Promise
|
|
474
|
-
if (typeof callback === 'function' || command.commandName === 'killCursors') {
|
|
475
|
-
var startTime = timestampGenerator.current();
|
|
476
|
-
// Emit the started event
|
|
477
|
-
self.emit('started', command);
|
|
478
|
-
|
|
479
|
-
// Emit succeeded event with killcursor if we have a legacy protocol
|
|
480
|
-
if (
|
|
481
|
-
command.commandName === 'killCursors' &&
|
|
482
|
-
this.topology.lastIsMaster() &&
|
|
483
|
-
this.topology.lastIsMaster().maxWireVersion < 4
|
|
484
|
-
) {
|
|
485
|
-
// Emit the succeeded command
|
|
486
|
-
command = {
|
|
487
|
-
duration: timestampGenerator.duration(startTime, timestampGenerator.current()),
|
|
488
|
-
commandName: commandName,
|
|
489
|
-
requestId: requestId,
|
|
490
|
-
operationId: cursor.operationId,
|
|
491
|
-
connectionId: cursor.topology.getConnection(),
|
|
492
|
-
reply: [{ ok: 1 }]
|
|
493
|
-
};
|
|
494
|
-
|
|
495
|
-
// Apply callback to the list of args
|
|
496
|
-
args.push(callback);
|
|
497
|
-
// Apply the call
|
|
498
|
-
func.apply(this, args);
|
|
499
|
-
// Emit the command
|
|
500
|
-
return self.emit('succeeded', command);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// Add our callback handler
|
|
504
|
-
args.push(function(err, r) {
|
|
505
|
-
if (err) {
|
|
506
|
-
// Command
|
|
507
|
-
var command = {
|
|
508
|
-
duration: timestampGenerator.duration(startTime, timestampGenerator.current()),
|
|
509
|
-
commandName: commandName,
|
|
510
|
-
requestId: requestId,
|
|
511
|
-
operationId: ourOpId,
|
|
512
|
-
connectionId: cursor.topology.getConnection(),
|
|
513
|
-
failure: err
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
// Emit the command
|
|
517
|
-
self.emit('failed', command);
|
|
518
|
-
} else {
|
|
519
|
-
if (r && r.documents) {
|
|
520
|
-
r = r.documents[0];
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (commandName.toLowerCase() === 'getmore' && (r == null || r.cursor == null)) {
|
|
524
|
-
r = {
|
|
525
|
-
cursor: {
|
|
526
|
-
id: cursor.cursorState.cursorId,
|
|
527
|
-
ns: cursor.ns,
|
|
528
|
-
nextBatch: cursor.cursorState.documents
|
|
529
|
-
},
|
|
530
|
-
ok: 1
|
|
531
|
-
};
|
|
532
|
-
} else if (
|
|
533
|
-
(commandName.toLowerCase() === 'find' ||
|
|
534
|
-
commandName.toLowerCase() === 'aggregate' ||
|
|
535
|
-
commandName.toLowerCase() === 'listcollections') &&
|
|
536
|
-
(r == null || r.cursor == null)
|
|
537
|
-
) {
|
|
538
|
-
r = {
|
|
539
|
-
cursor: {
|
|
540
|
-
id: cursor.cursorState.cursorId,
|
|
541
|
-
ns: cursor.ns,
|
|
542
|
-
firstBatch: cursor.cursorState.documents
|
|
543
|
-
},
|
|
544
|
-
ok: 1
|
|
545
|
-
};
|
|
546
|
-
} else if (commandName.toLowerCase() === 'killcursors' && r == null) {
|
|
547
|
-
r = {
|
|
548
|
-
cursorsUnknown: [cursor.cursorState.lastCursorId],
|
|
549
|
-
ok: 1
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// cursor id is zero, we can issue success command
|
|
554
|
-
command = {
|
|
555
|
-
duration: timestampGenerator.duration(startTime, timestampGenerator.current()),
|
|
556
|
-
commandName: commandName,
|
|
557
|
-
requestId: requestId,
|
|
558
|
-
operationId: cursor.operationId,
|
|
559
|
-
connectionId: cursor.topology.getConnection(),
|
|
560
|
-
reply: r && r.result ? r.result : r
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
// Emit the command
|
|
564
|
-
self.emit('succeeded', command);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// Return
|
|
568
|
-
if (!callback) return;
|
|
569
|
-
|
|
570
|
-
// Return to caller
|
|
571
|
-
callback(err, r);
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
// Apply the call
|
|
575
|
-
func.apply(this, args);
|
|
576
|
-
} else {
|
|
577
|
-
// Assume promise, push back the missing value
|
|
578
|
-
args.push(callback);
|
|
579
|
-
// Get the promise
|
|
580
|
-
var promise = func.apply(this, args);
|
|
581
|
-
// Return a new promise
|
|
582
|
-
return new cursor.s.promiseLibrary(function(resolve, reject) {
|
|
583
|
-
var startTime = timestampGenerator.current();
|
|
584
|
-
// Emit the started event
|
|
585
|
-
self.emit('started', command);
|
|
586
|
-
// Execute the function
|
|
587
|
-
promise
|
|
588
|
-
.then(function() {
|
|
589
|
-
// cursor id is zero, we can issue success command
|
|
590
|
-
var command = {
|
|
591
|
-
duration: timestampGenerator.duration(startTime, timestampGenerator.current()),
|
|
592
|
-
commandName: commandName,
|
|
593
|
-
requestId: requestId,
|
|
594
|
-
operationId: cursor.operationId,
|
|
595
|
-
connectionId: cursor.topology.getConnection(),
|
|
596
|
-
reply: cursor.cursorState.documents
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
// Emit the command
|
|
600
|
-
self.emit('succeeded', command);
|
|
601
|
-
})
|
|
602
|
-
.catch(function(err) {
|
|
603
|
-
// Command
|
|
604
|
-
var command = {
|
|
605
|
-
duration: timestampGenerator.duration(startTime, timestampGenerator.current()),
|
|
606
|
-
commandName: commandName,
|
|
607
|
-
requestId: requestId,
|
|
608
|
-
operationId: ourOpId,
|
|
609
|
-
connectionId: cursor.topology.getConnection(),
|
|
610
|
-
failure: err
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
// Emit the command
|
|
614
|
-
self.emit('failed', command);
|
|
615
|
-
// reject the promise
|
|
616
|
-
reject(err);
|
|
617
|
-
});
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
});
|
|
622
|
-
});
|
|
623
|
-
};
|
|
624
|
-
|
|
625
|
-
inherits(Instrumentation, EventEmitter);
|
|
626
|
-
|
|
627
|
-
Instrumentation.prototype.uninstrument = function() {
|
|
628
|
-
for (var i = 0; i < this.overloads.length; i++) {
|
|
629
|
-
var obj = this.overloads[i];
|
|
630
|
-
obj.proto[obj.name] = obj.func;
|
|
23
|
+
if (typeof callback === 'function') callback(null, this);
|
|
631
24
|
}
|
|
632
25
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
};
|
|
26
|
+
uninstrument() {
|
|
27
|
+
this.$MongoClient.prototype.connect = this.$prototypeConnect;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
638
30
|
|
|
639
31
|
module.exports = Instrumentation;
|
package/lib/bulk/common.js
CHANGED
|
@@ -15,28 +15,6 @@ var INSERT = 1;
|
|
|
15
15
|
var UPDATE = 2;
|
|
16
16
|
var REMOVE = 3;
|
|
17
17
|
|
|
18
|
-
// Get write concern
|
|
19
|
-
var writeConcern = function(target, col, options) {
|
|
20
|
-
var writeConcern = {};
|
|
21
|
-
|
|
22
|
-
// Collection level write concern
|
|
23
|
-
if (col.writeConcern && col.writeConcern.w != null) writeConcern.w = col.writeConcern.w;
|
|
24
|
-
if (col.writeConcern && col.writeConcern.j != null) writeConcern.j = col.writeConcern.j;
|
|
25
|
-
if (col.writeConcern && col.writeConcern.fsync != null)
|
|
26
|
-
writeConcern.fsync = col.writeConcern.fsync;
|
|
27
|
-
if (col.writeConcern && col.writeConcern.wtimeout != null)
|
|
28
|
-
writeConcern.wtimeout = col.writeConcern.wtimeout;
|
|
29
|
-
|
|
30
|
-
// Options level write concern
|
|
31
|
-
if (options && options.w != null) writeConcern.w = options.w;
|
|
32
|
-
if (options && options.wtimeout != null) writeConcern.wtimeout = options.wtimeout;
|
|
33
|
-
if (options && options.j != null) writeConcern.j = options.j;
|
|
34
|
-
if (options && options.fsync != null) writeConcern.fsync = options.fsync;
|
|
35
|
-
|
|
36
|
-
// Return write concern
|
|
37
|
-
return writeConcern;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
18
|
/**
|
|
41
19
|
* Helper function to define properties
|
|
42
20
|
* @ignore
|
|
@@ -455,7 +433,6 @@ exports.Batch = Batch;
|
|
|
455
433
|
exports.LegacyOp = LegacyOp;
|
|
456
434
|
exports.mergeBatchResults = mergeBatchResults;
|
|
457
435
|
exports.cloneOptions = cloneOptions;
|
|
458
|
-
exports.writeConcern = writeConcern;
|
|
459
436
|
exports.INVALID_BSON_ERROR = INVALID_BSON_ERROR;
|
|
460
437
|
exports.WRITE_CONCERN_ERROR = WRITE_CONCERN_ERROR;
|
|
461
438
|
exports.MULTIPLE_ERROR = MULTIPLE_ERROR;
|