mongodb 2.1.0-alpha → 2.1.2
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/HISTORY.md +574 -429
- package/Makefile +2 -5
- package/README.md +108 -15
- package/conf.json +17 -13
- package/index.js +13 -2
- package/lib/admin.js +113 -47
- package/lib/aggregation_cursor.js +56 -28
- package/lib/apm.js +608 -0
- package/lib/bulk/common.js +7 -7
- package/lib/bulk/ordered.js +56 -17
- package/lib/bulk/unordered.js +52 -14
- package/lib/collection.js +671 -212
- package/lib/command_cursor.js +60 -32
- package/lib/cursor.js +313 -115
- package/lib/db.js +264 -105
- package/lib/gridfs/chunk.js +26 -29
- package/lib/gridfs/grid_store.js +150 -64
- package/lib/gridfs-stream/download.js +310 -0
- package/lib/gridfs-stream/index.js +335 -0
- package/lib/gridfs-stream/upload.js +450 -0
- package/lib/metadata.js +64 -0
- package/lib/mongo_client.js +69 -39
- package/lib/mongos.js +65 -20
- package/lib/replset.js +69 -34
- package/lib/server.js +35 -1
- package/lib/topology_base.js +22 -10
- package/lib/url_parser.js +111 -13
- package/lib/utils.js +9 -8
- package/mongolabs.js +427 -0
- package/package.json +8 -6
- package/t.js +68 -51
- package/test.js +12 -0
- package/test_boot/boot.sh +3 -0
- package/test_boot/ca.pem +49 -0
- package/test_boot/client.pem +48 -0
- package/test_boot/client_password.pem +51 -0
- package/test_boot/connect.js +29 -0
- package/test_boot/data/WiredTiger +2 -0
- package/test_boot/data/WiredTiger.lock +1 -0
- package/test_boot/data/WiredTiger.turtle +6 -0
- package/test_boot/data/WiredTiger.wt +0 -0
- package/test_boot/data/WiredTigerLAS.wt +0 -0
- package/test_boot/data/_mdb_catalog.wt +0 -0
- package/test_boot/data/collection-0-757073248613337118.wt +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-44-37Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-45-15Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-46-31Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-47-25Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-49-07Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-50-41Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-50-53Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-52-31Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-54-53Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-55-09Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-55-38Z-00000 +0 -0
- package/test_boot/data/index-1-757073248613337118.wt +0 -0
- package/test_boot/data/mongod.lock +0 -0
- package/test_boot/data/sizeStorer.wt +0 -0
- package/test_boot/data/storage.bson +0 -0
- package/test_boot/server_password.pem +51 -0
- package/.travis.yml +0 -10
- package/t1.js +0 -59
- package/wercker.yml +0 -19
package/lib/db.js
CHANGED
|
@@ -16,6 +16,7 @@ var EventEmitter = require('events').EventEmitter
|
|
|
16
16
|
, CoreReadPreference = require('mongodb-core').ReadPreference
|
|
17
17
|
, MongoError = require('mongodb-core').MongoError
|
|
18
18
|
, ObjectID = require('mongodb-core').ObjectID
|
|
19
|
+
, Define = require('./metadata')
|
|
19
20
|
, Logger = require('mongodb-core').Logger
|
|
20
21
|
, Collection = require('./collection')
|
|
21
22
|
, crypto = require('crypto');
|
|
@@ -53,14 +54,15 @@ var debugFields = ['authSource', 'w', 'wtimeout', 'j', 'native_parser', 'forceSe
|
|
|
53
54
|
* @param {boolean} [options.native_parser=true] Select C++ bson parser instead of JavaScript parser.
|
|
54
55
|
* @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
|
|
55
56
|
* @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
|
|
57
|
+
* @param {Boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
|
|
56
58
|
* @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
|
|
57
59
|
* @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
|
|
58
60
|
* @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited.
|
|
59
|
-
* @param {number} [options.numberOfRetries=5] Number of retries off connection.
|
|
60
|
-
* @param {number} [options.retryMiliSeconds=500] Number of milliseconds between retries.
|
|
61
61
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
62
62
|
* @param {object} [options.pkFactory=null] A primary key factory object for generation of custom _id keys.
|
|
63
63
|
* @param {object} [options.promiseLibrary=null] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
|
|
64
|
+
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
65
|
+
* @param {object} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
|
|
64
66
|
* @property {(Server|ReplSet|Mongos)} serverConfig Get the current db topology.
|
|
65
67
|
* @property {number} bufferMaxEntries Current bufferMaxEntries value for the database
|
|
66
68
|
* @property {string} databaseName The name of the database this instance represents.
|
|
@@ -99,6 +101,8 @@ var Db = function(databaseName, topology, options) {
|
|
|
99
101
|
this.s = {
|
|
100
102
|
// Database name
|
|
101
103
|
databaseName: databaseName
|
|
104
|
+
// DbCache
|
|
105
|
+
, dbCache: {}
|
|
102
106
|
// Children db's
|
|
103
107
|
, children: []
|
|
104
108
|
// Topology
|
|
@@ -123,6 +127,10 @@ var Db = function(databaseName, topology, options) {
|
|
|
123
127
|
, nativeParser: options.nativeParser || options.native_parser
|
|
124
128
|
// Promise library
|
|
125
129
|
, promiseLibrary: promiseLibrary
|
|
130
|
+
// No listener
|
|
131
|
+
, noListener: typeof options.noListener == 'boolean' ? options.noListener : false
|
|
132
|
+
// ReadConcern
|
|
133
|
+
, readConcern: options.readConcern
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
// Ensure we have a valid db name
|
|
@@ -180,12 +188,13 @@ var Db = function(databaseName, topology, options) {
|
|
|
180
188
|
|
|
181
189
|
// This is a child db, do not register any listeners
|
|
182
190
|
if(options.parentDb) return;
|
|
191
|
+
if(this.s.noListener) return;
|
|
183
192
|
|
|
184
193
|
// Add listeners
|
|
185
|
-
topology.
|
|
186
|
-
topology.
|
|
194
|
+
topology.on('error', createListener(self, 'error', self));
|
|
195
|
+
topology.on('timeout', createListener(self, 'timeout', self));
|
|
187
196
|
topology.on('close', createListener(self, 'close', self));
|
|
188
|
-
topology.
|
|
197
|
+
topology.on('parseError', createListener(self, 'parseError', self));
|
|
189
198
|
topology.once('open', createListener(self, 'open', self));
|
|
190
199
|
topology.once('fullsetup', createListener(self, 'fullsetup', self));
|
|
191
200
|
topology.once('all', createListener(self, 'all', self));
|
|
@@ -194,6 +203,8 @@ var Db = function(databaseName, topology, options) {
|
|
|
194
203
|
|
|
195
204
|
inherits(Db, EventEmitter);
|
|
196
205
|
|
|
206
|
+
var define = Db.define = new Define('Db', Db, false);
|
|
207
|
+
|
|
197
208
|
/**
|
|
198
209
|
* The callback format for the Db.open method
|
|
199
210
|
* @callback Db~openCallback
|
|
@@ -214,13 +225,13 @@ var open = function(self, callback) {
|
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
internalCallback(null, self);
|
|
217
|
-
});
|
|
228
|
+
});
|
|
218
229
|
}
|
|
219
230
|
|
|
220
231
|
/**
|
|
221
232
|
* Open the database
|
|
222
233
|
* @method
|
|
223
|
-
* @param {Db~openCallback} callback Callback
|
|
234
|
+
* @param {Db~openCallback} [callback] Callback
|
|
224
235
|
* @return {Promise} returns Promise if no callback passed
|
|
225
236
|
*/
|
|
226
237
|
Db.prototype.open = function(callback) {
|
|
@@ -236,6 +247,8 @@ Db.prototype.open = function(callback) {
|
|
|
236
247
|
});
|
|
237
248
|
}
|
|
238
249
|
|
|
250
|
+
define.classMethod('open', {callback: true, promise:true});
|
|
251
|
+
|
|
239
252
|
/**
|
|
240
253
|
* The callback format for results
|
|
241
254
|
* @callback Db~resultCallback
|
|
@@ -244,6 +257,9 @@ Db.prototype.open = function(callback) {
|
|
|
244
257
|
*/
|
|
245
258
|
|
|
246
259
|
var executeCommand = function(self, command, options, callback) {
|
|
260
|
+
// Did the user destroy the topology
|
|
261
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
262
|
+
// Get the db name we are executing against
|
|
247
263
|
var dbName = options.dbName || options.authdb || self.s.databaseName;
|
|
248
264
|
// If we have a readPreference set
|
|
249
265
|
if(options.readPreference == null && self.s.readPreference) {
|
|
@@ -265,6 +281,7 @@ var executeCommand = function(self, command, options, callback) {
|
|
|
265
281
|
// Execute command
|
|
266
282
|
self.s.topology.command(f('%s.$cmd', dbName), command, options, function(err, result) {
|
|
267
283
|
if(err) return handleCallback(callback, err);
|
|
284
|
+
if(options.full) return handleCallback(callback, null, result);
|
|
268
285
|
handleCallback(callback, null, result.result);
|
|
269
286
|
});
|
|
270
287
|
}
|
|
@@ -275,8 +292,7 @@ var executeCommand = function(self, command, options, callback) {
|
|
|
275
292
|
* @param {object} command The command hash
|
|
276
293
|
* @param {object} [options=null] Optional settings.
|
|
277
294
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
278
|
-
* @param {
|
|
279
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
295
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
280
296
|
* @return {Promise} returns Promise if no callback passed
|
|
281
297
|
*/
|
|
282
298
|
Db.prototype.command = function(command, options, callback) {
|
|
@@ -285,7 +301,7 @@ Db.prototype.command = function(command, options, callback) {
|
|
|
285
301
|
if(typeof options == 'function') callback = options, options = {};
|
|
286
302
|
// Clone the options
|
|
287
303
|
options = shallowClone(options);
|
|
288
|
-
|
|
304
|
+
|
|
289
305
|
// Do we have a callback
|
|
290
306
|
if(typeof callback == 'function') return executeCommand(self, command, options, callback);
|
|
291
307
|
// Return a promise
|
|
@@ -297,6 +313,8 @@ Db.prototype.command = function(command, options, callback) {
|
|
|
297
313
|
});
|
|
298
314
|
}
|
|
299
315
|
|
|
316
|
+
define.classMethod('command', {callback: true, promise:true});
|
|
317
|
+
|
|
300
318
|
/**
|
|
301
319
|
* The callback format for results
|
|
302
320
|
* @callback Db~noResultCallback
|
|
@@ -308,7 +326,7 @@ Db.prototype.command = function(command, options, callback) {
|
|
|
308
326
|
* Close the db and it's underlying connections
|
|
309
327
|
* @method
|
|
310
328
|
* @param {boolean} force Force close, emitting no events
|
|
311
|
-
* @param {Db~noResultCallback} callback The result callback
|
|
329
|
+
* @param {Db~noResultCallback} [callback] The result callback
|
|
312
330
|
* @return {Promise} returns Promise if no callback passed
|
|
313
331
|
*/
|
|
314
332
|
Db.prototype.close = function(force, callback) {
|
|
@@ -325,13 +343,13 @@ Db.prototype.close = function(force, callback) {
|
|
|
325
343
|
// Fire close on all children
|
|
326
344
|
for(var i = 0; i < this.s.children.length; i++) {
|
|
327
345
|
this.s.children[i].emit('close');
|
|
328
|
-
}
|
|
346
|
+
}
|
|
329
347
|
}
|
|
330
348
|
|
|
331
349
|
// Remove listeners after emit
|
|
332
|
-
self.removeAllListeners('close');
|
|
350
|
+
self.removeAllListeners('close');
|
|
333
351
|
}
|
|
334
|
-
|
|
352
|
+
|
|
335
353
|
// Close parent db if set
|
|
336
354
|
if(this.s.parentDb) this.s.parentDb.close();
|
|
337
355
|
// Callback after next event loop tick
|
|
@@ -345,6 +363,8 @@ Db.prototype.close = function(force, callback) {
|
|
|
345
363
|
});
|
|
346
364
|
}
|
|
347
365
|
|
|
366
|
+
define.classMethod('close', {callback: true, promise:true});
|
|
367
|
+
|
|
348
368
|
/**
|
|
349
369
|
* Return the Admin db instance
|
|
350
370
|
* @method
|
|
@@ -354,6 +374,8 @@ Db.prototype.admin = function() {
|
|
|
354
374
|
return new Admin(this, this.s.topology, this.s.promiseLibrary);
|
|
355
375
|
};
|
|
356
376
|
|
|
377
|
+
define.classMethod('admin', {callback: false, promise:false, returns: [Admin]});
|
|
378
|
+
|
|
357
379
|
/**
|
|
358
380
|
* The callback format for the collection method, must be used if strict is specified
|
|
359
381
|
* @callback Db~collectionResultCallback
|
|
@@ -376,6 +398,8 @@ Db.prototype.admin = function() {
|
|
|
376
398
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
377
399
|
* @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
|
|
378
400
|
* @param {boolean} [options.strict=false] Returns an error if the collection does not exist
|
|
401
|
+
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
402
|
+
* @param {object} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
|
|
379
403
|
* @param {Db~collectionResultCallback} callback The collection result callback
|
|
380
404
|
* @return {Collection} return the new Collection instance if not in strict mode
|
|
381
405
|
*/
|
|
@@ -387,6 +411,14 @@ Db.prototype.collection = function(name, options, callback) {
|
|
|
387
411
|
// Set the promise library
|
|
388
412
|
options.promiseLibrary = this.s.promiseLibrary;
|
|
389
413
|
|
|
414
|
+
// If we have not set a collection level readConcern set the db level one
|
|
415
|
+
options.readConcern = options.readConcern || this.s.readConcern;
|
|
416
|
+
|
|
417
|
+
// Do we have ignoreUndefined set
|
|
418
|
+
if(this.s.options.ignoreUndefined) {
|
|
419
|
+
options.ignoreUndefined = this.s.options.ignoreUndefined;
|
|
420
|
+
}
|
|
421
|
+
|
|
390
422
|
// Execute
|
|
391
423
|
if(options == null || !options.strict) {
|
|
392
424
|
try {
|
|
@@ -417,15 +449,19 @@ Db.prototype.collection = function(name, options, callback) {
|
|
|
417
449
|
});
|
|
418
450
|
}
|
|
419
451
|
|
|
452
|
+
define.classMethod('collection', {callback: true, promise:false, returns: [Collection]});
|
|
453
|
+
|
|
420
454
|
var createCollection = function(self, name, options, callback) {
|
|
421
455
|
// Get the write concern options
|
|
422
456
|
var finalOptions = writeConcern(shallowClone(options), self, options);
|
|
457
|
+
// Did the user destroy the topology
|
|
458
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
423
459
|
|
|
424
460
|
// Check if we have the name
|
|
425
461
|
self.listCollections({name: name}).toArray(function(err, collections) {
|
|
426
462
|
if(err != null) return handleCallback(callback, err, null);
|
|
427
463
|
if(collections.length > 0 && finalOptions.strict) {
|
|
428
|
-
return handleCallback(callback,
|
|
464
|
+
return handleCallback(callback, MongoError.create({message: f("Collection %s already exists. Currently in strict mode.", name), driver:true}), null);
|
|
429
465
|
} else if (collections.length > 0) {
|
|
430
466
|
try { return handleCallback(callback, null, new Collection(self, self.s.topology, self.s.databaseName, name, self.s.pkFactory, options)); }
|
|
431
467
|
catch(err) { return handleCallback(callback, err); }
|
|
@@ -445,7 +481,7 @@ var createCollection = function(self, name, options, callback) {
|
|
|
445
481
|
if(err) return handleCallback(callback, err);
|
|
446
482
|
handleCallback(callback, null, new Collection(self, self.s.topology, self.s.databaseName, name, self.s.pkFactory, options));
|
|
447
483
|
});
|
|
448
|
-
});
|
|
484
|
+
});
|
|
449
485
|
}
|
|
450
486
|
|
|
451
487
|
/**
|
|
@@ -466,7 +502,7 @@ var createCollection = function(self, name, options, callback) {
|
|
|
466
502
|
* @param {number} [options.size=null] The size of the capped collection in bytes.
|
|
467
503
|
* @param {number} [options.max=null] The maximum number of documents in the capped collection.
|
|
468
504
|
* @param {boolean} [options.autoIndexId=true] Create an index on the _id field of the document, True by default on MongoDB 2.2 or higher off for version < 2.2.
|
|
469
|
-
* @param {Db~collectionResultCallback} callback The results callback
|
|
505
|
+
* @param {Db~collectionResultCallback} [callback] The results callback
|
|
470
506
|
* @return {Promise} returns Promise if no callback passed
|
|
471
507
|
*/
|
|
472
508
|
Db.prototype.createCollection = function(name, options, callback) {
|
|
@@ -477,6 +513,9 @@ Db.prototype.createCollection = function(name, options, callback) {
|
|
|
477
513
|
name = args.length ? args.shift() : null;
|
|
478
514
|
options = args.length ? args.shift() || {} : {};
|
|
479
515
|
|
|
516
|
+
// Do we have a promisesLibrary
|
|
517
|
+
options.promiseLibrary = options.promiseLibrary || this.s.promiseLibrary;
|
|
518
|
+
|
|
480
519
|
// Check if the callback is in fact a string
|
|
481
520
|
if(typeof callback == 'string') name = callback;
|
|
482
521
|
|
|
@@ -490,13 +529,15 @@ Db.prototype.createCollection = function(name, options, callback) {
|
|
|
490
529
|
});
|
|
491
530
|
}
|
|
492
531
|
|
|
532
|
+
define.classMethod('createCollection', {callback: true, promise:true});
|
|
533
|
+
|
|
493
534
|
/**
|
|
494
535
|
* Get all the db statistics.
|
|
495
536
|
*
|
|
496
537
|
* @method
|
|
497
538
|
* @param {object} [options=null] Optional settings.
|
|
498
539
|
* @param {number} [options.scale=null] Divide the returned sizes by scale value.
|
|
499
|
-
* @param {Db~resultCallback} callback The collection result callback
|
|
540
|
+
* @param {Db~resultCallback} [callback] The collection result callback
|
|
500
541
|
* @return {Promise} returns Promise if no callback passed
|
|
501
542
|
*/
|
|
502
543
|
Db.prototype.stats = function(options, callback) {
|
|
@@ -510,6 +551,8 @@ Db.prototype.stats = function(options, callback) {
|
|
|
510
551
|
return this.command(commandObject, options, callback);
|
|
511
552
|
}
|
|
512
553
|
|
|
554
|
+
define.classMethod('stats', {callback: true, promise:true});
|
|
555
|
+
|
|
513
556
|
// Transformation methods for cursor results
|
|
514
557
|
var listCollectionsTranforms = function(databaseName) {
|
|
515
558
|
var matching = f('%s.', databaseName);
|
|
@@ -534,6 +577,7 @@ var listCollectionsTranforms = function(databaseName) {
|
|
|
534
577
|
* @param {object} filter Query to filter collections by
|
|
535
578
|
* @param {object} [options=null] Optional settings.
|
|
536
579
|
* @param {number} [options.batchSize=null] The batchSize for the returned command cursor or if pre 2.8 the systems batch collection
|
|
580
|
+
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
537
581
|
* @return {CommandCursor}
|
|
538
582
|
*/
|
|
539
583
|
Db.prototype.listCollections = function(filter, options) {
|
|
@@ -544,7 +588,6 @@ Db.prototype.listCollections = function(filter, options) {
|
|
|
544
588
|
options = shallowClone(options);
|
|
545
589
|
// Set the promise library
|
|
546
590
|
options.promiseLibrary = this.s.promiseLibrary;
|
|
547
|
-
|
|
548
591
|
// We have a list collections command
|
|
549
592
|
if(this.serverConfig.capabilities().hasListCollectionsCommand) {
|
|
550
593
|
// Cursor options
|
|
@@ -555,8 +598,12 @@ Db.prototype.listCollections = function(filter, options) {
|
|
|
555
598
|
options.cursorFactory = CommandCursor;
|
|
556
599
|
// Filter out the correct field values
|
|
557
600
|
options.transforms = listCollectionsTranforms(this.s.databaseName);
|
|
558
|
-
//
|
|
559
|
-
|
|
601
|
+
// Create the cursor
|
|
602
|
+
var cursor = this.s.topology.cursor(f('%s.$cmd', this.s.databaseName), command, options);
|
|
603
|
+
// Do we have a readPreference, apply it
|
|
604
|
+
if(options.readPeference) cursor.setReadPreference(options.readPeference);
|
|
605
|
+
// Return the cursor
|
|
606
|
+
return cursor;
|
|
560
607
|
}
|
|
561
608
|
|
|
562
609
|
// We cannot use the listCollectionsCommand
|
|
@@ -581,19 +628,26 @@ Db.prototype.listCollections = function(filter, options) {
|
|
|
581
628
|
}
|
|
582
629
|
|
|
583
630
|
// Return options
|
|
584
|
-
var
|
|
631
|
+
var _options = {transforms: listCollectionsTranforms(this.s.databaseName)}
|
|
585
632
|
// Get the cursor
|
|
586
|
-
var cursor = this.collection(Db.SYSTEM_NAMESPACE_COLLECTION).find(filter,
|
|
633
|
+
var cursor = this.collection(Db.SYSTEM_NAMESPACE_COLLECTION).find(filter, _options);
|
|
634
|
+
// Do we have a readPreference, apply it
|
|
635
|
+
if(options.readPeference) cursor.setReadPreference(options.readPeference);
|
|
587
636
|
// Set the passed in batch size if one was provided
|
|
588
637
|
if(options.batchSize) cursor = cursor.batchSize(options.batchSize);
|
|
589
638
|
// We have a fallback mode using legacy systems collections
|
|
590
639
|
return cursor;
|
|
591
640
|
};
|
|
592
641
|
|
|
642
|
+
define.classMethod('listCollections', {callback: false, promise:false, returns: [CommandCursor]});
|
|
643
|
+
|
|
593
644
|
var evaluate = function(self, code, parameters, options, callback) {
|
|
594
645
|
var finalCode = code;
|
|
595
646
|
var finalParameters = [];
|
|
596
647
|
|
|
648
|
+
// Did the user destroy the topology
|
|
649
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
650
|
+
|
|
597
651
|
// If not a code object translate to one
|
|
598
652
|
if(!(finalCode instanceof Code)) finalCode = new Code(finalCode);
|
|
599
653
|
// Ensure the parameters are correct
|
|
@@ -617,9 +671,9 @@ var evaluate = function(self, code, parameters, options, callback) {
|
|
|
617
671
|
self.command(cmd, options, function(err, result) {
|
|
618
672
|
if(err) return handleCallback(callback, err, null);
|
|
619
673
|
if(result && result.ok == 1) return handleCallback(callback, null, result.retval);
|
|
620
|
-
if(result) return handleCallback(callback,
|
|
674
|
+
if(result) return handleCallback(callback, MongoError.create({message: f("eval failed: %s", result.errmsg), driver:true}), null);
|
|
621
675
|
handleCallback(callback, err, result);
|
|
622
|
-
});
|
|
676
|
+
});
|
|
623
677
|
}
|
|
624
678
|
|
|
625
679
|
/**
|
|
@@ -630,7 +684,8 @@ var evaluate = function(self, code, parameters, options, callback) {
|
|
|
630
684
|
* @param {(object|array)} parameters The parameters for the call.
|
|
631
685
|
* @param {object} [options=null] Optional settings.
|
|
632
686
|
* @param {boolean} [options.nolock=false] Tell MongoDB not to block on the evaulation of the javascript.
|
|
633
|
-
* @param {Db~resultCallback} callback The results callback
|
|
687
|
+
* @param {Db~resultCallback} [callback] The results callback
|
|
688
|
+
* @deprecated Eval is deprecated on MongoDB 3.2 and forward
|
|
634
689
|
* @return {Promise} returns Promise if no callback passed
|
|
635
690
|
*/
|
|
636
691
|
Db.prototype.eval = function(code, parameters, options, callback) {
|
|
@@ -652,6 +707,8 @@ Db.prototype.eval = function(code, parameters, options, callback) {
|
|
|
652
707
|
});
|
|
653
708
|
};
|
|
654
709
|
|
|
710
|
+
define.classMethod('eval', {callback: true, promise:true});
|
|
711
|
+
|
|
655
712
|
/**
|
|
656
713
|
* Rename a collection.
|
|
657
714
|
*
|
|
@@ -660,7 +717,7 @@ Db.prototype.eval = function(code, parameters, options, callback) {
|
|
|
660
717
|
* @param {string} toCollection New name of of the collection.
|
|
661
718
|
* @param {object} [options=null] Optional settings.
|
|
662
719
|
* @param {boolean} [options.dropTarget=false] Drop the target name collection if it previously exists.
|
|
663
|
-
* @param {Db~collectionResultCallback} callback The results callback
|
|
720
|
+
* @param {Db~collectionResultCallback} [callback] The results callback
|
|
664
721
|
* @return {Promise} returns Promise if no callback passed
|
|
665
722
|
*/
|
|
666
723
|
Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) {
|
|
@@ -673,7 +730,7 @@ Db.prototype.renameCollection = function(fromCollection, toCollection, options,
|
|
|
673
730
|
// Check if the callback is in fact a string
|
|
674
731
|
if(typeof callback == 'function') {
|
|
675
732
|
return this.collection(fromCollection).rename(toCollection, options, callback);
|
|
676
|
-
}
|
|
733
|
+
}
|
|
677
734
|
|
|
678
735
|
// Return a promise
|
|
679
736
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
@@ -684,12 +741,14 @@ Db.prototype.renameCollection = function(fromCollection, toCollection, options,
|
|
|
684
741
|
});
|
|
685
742
|
};
|
|
686
743
|
|
|
744
|
+
define.classMethod('renameCollection', {callback: true, promise:true});
|
|
745
|
+
|
|
687
746
|
/**
|
|
688
747
|
* Drop a collection from the database, removing it permanently. New accesses will create a new collection.
|
|
689
748
|
*
|
|
690
749
|
* @method
|
|
691
750
|
* @param {string} name Name of collection to drop
|
|
692
|
-
* @param {Db~resultCallback} callback The results callback
|
|
751
|
+
* @param {Db~resultCallback} [callback] The results callback
|
|
693
752
|
* @return {Promise} returns Promise if no callback passed
|
|
694
753
|
*/
|
|
695
754
|
Db.prototype.dropCollection = function(name, callback) {
|
|
@@ -700,6 +759,8 @@ Db.prototype.dropCollection = function(name, callback) {
|
|
|
700
759
|
|
|
701
760
|
// Check if the callback is in fact a string
|
|
702
761
|
if(typeof callback == 'function') return this.command(cmd, this.s.options, function(err, result) {
|
|
762
|
+
// Did the user destroy the topology
|
|
763
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
703
764
|
if(err) return handleCallback(callback, err);
|
|
704
765
|
if(result.ok) return handleCallback(callback, null, true);
|
|
705
766
|
handleCallback(callback, null, false);
|
|
@@ -709,13 +770,17 @@ Db.prototype.dropCollection = function(name, callback) {
|
|
|
709
770
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
710
771
|
// Execute command
|
|
711
772
|
self.command(cmd, self.s.options, function(err, result) {
|
|
712
|
-
|
|
773
|
+
// Did the user destroy the topology
|
|
774
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return reject(new MongoError('topology was destroyed'));
|
|
775
|
+
if(err) return reject(err);
|
|
713
776
|
if(result.ok) return resolve(true);
|
|
714
777
|
resolve(false);
|
|
715
778
|
});
|
|
716
779
|
});
|
|
717
780
|
};
|
|
718
781
|
|
|
782
|
+
define.classMethod('dropCollection', {callback: true, promise:true});
|
|
783
|
+
|
|
719
784
|
/**
|
|
720
785
|
* Drop a database.
|
|
721
786
|
*
|
|
@@ -725,12 +790,13 @@ Db.prototype.dropCollection = function(name, callback) {
|
|
|
725
790
|
*/
|
|
726
791
|
Db.prototype.dropDatabase = function(callback) {
|
|
727
792
|
var self = this;
|
|
728
|
-
if(typeof options == 'function') callback = options, options = {};
|
|
729
793
|
// Drop database command
|
|
730
794
|
var cmd = {'dropDatabase':1};
|
|
731
795
|
|
|
732
796
|
// Check if the callback is in fact a string
|
|
733
797
|
if(typeof callback == 'function') return this.command(cmd, this.s.options, function(err, result) {
|
|
798
|
+
// Did the user destroy the topology
|
|
799
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
734
800
|
if(callback == null) return;
|
|
735
801
|
if(err) return handleCallback(callback, err, null);
|
|
736
802
|
handleCallback(callback, null, result.ok ? true : false);
|
|
@@ -740,20 +806,23 @@ Db.prototype.dropDatabase = function(callback) {
|
|
|
740
806
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
741
807
|
// Execute command
|
|
742
808
|
self.command(cmd, self.s.options, function(err, result) {
|
|
743
|
-
|
|
809
|
+
// Did the user destroy the topology
|
|
810
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return reject(new MongoError('topology was destroyed'));
|
|
811
|
+
if(err) return reject(err);
|
|
744
812
|
if(result.ok) return resolve(true);
|
|
745
813
|
resolve(false);
|
|
746
814
|
});
|
|
747
815
|
});
|
|
748
816
|
}
|
|
749
817
|
|
|
818
|
+
define.classMethod('dropDatabase', {callback: true, promise:true});
|
|
819
|
+
|
|
750
820
|
/**
|
|
751
821
|
* The callback format for the collections method.
|
|
752
822
|
* @callback Db~collectionsResultCallback
|
|
753
823
|
* @param {MongoError} error An error instance representing the error during the execution.
|
|
754
824
|
* @param {Collection[]} collections An array of all the collections objects for the db instance.
|
|
755
825
|
*/
|
|
756
|
-
|
|
757
826
|
var collections = function(self, callback) {
|
|
758
827
|
// Let's get the collection names
|
|
759
828
|
self.listCollections().toArray(function(err, documents) {
|
|
@@ -767,7 +836,7 @@ var collections = function(self, callback) {
|
|
|
767
836
|
handleCallback(callback, null, documents.map(function(d) {
|
|
768
837
|
return new Collection(self, self.s.topology, self.s.databaseName, d.name.replace(self.s.databaseName + ".", ''), self.s.pkFactory, self.s.options);
|
|
769
838
|
}));
|
|
770
|
-
});
|
|
839
|
+
});
|
|
771
840
|
}
|
|
772
841
|
|
|
773
842
|
/**
|
|
@@ -791,6 +860,8 @@ Db.prototype.collections = function(callback) {
|
|
|
791
860
|
});
|
|
792
861
|
};
|
|
793
862
|
|
|
863
|
+
define.classMethod('collections', {callback: true, promise:true});
|
|
864
|
+
|
|
794
865
|
/**
|
|
795
866
|
* Runs a command on the database as admin.
|
|
796
867
|
* @method
|
|
@@ -798,7 +869,7 @@ Db.prototype.collections = function(callback) {
|
|
|
798
869
|
* @param {object} [options=null] Optional settings.
|
|
799
870
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
800
871
|
* @param {number} [options.maxTimeMS=null] Number of milliseconds to wait before aborting the query.
|
|
801
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
872
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
802
873
|
* @return {Promise} returns Promise if no callback passed
|
|
803
874
|
*/
|
|
804
875
|
Db.prototype.executeDbAdminCommand = function(selector, options, callback) {
|
|
@@ -812,6 +883,8 @@ Db.prototype.executeDbAdminCommand = function(selector, options, callback) {
|
|
|
812
883
|
|
|
813
884
|
// Return the callback
|
|
814
885
|
if(typeof callback == 'function') return self.s.topology.command('admin.$cmd', selector, options, function(err, result) {
|
|
886
|
+
// Did the user destroy the topology
|
|
887
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
815
888
|
if(err) return handleCallback(callback, err);
|
|
816
889
|
handleCallback(callback, null, result.result);
|
|
817
890
|
});
|
|
@@ -819,37 +892,15 @@ Db.prototype.executeDbAdminCommand = function(selector, options, callback) {
|
|
|
819
892
|
// Return promise
|
|
820
893
|
return new self.s.promiseLibrary(function(resolve, reject) {
|
|
821
894
|
self.s.topology.command('admin.$cmd', selector, options, function(err, result) {
|
|
895
|
+
// Did the user destroy the topology
|
|
896
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return reject(new MongoError('topology was destroyed'));
|
|
822
897
|
if(err) return reject(err);
|
|
823
898
|
resolve(result.result);
|
|
824
899
|
});
|
|
825
900
|
});
|
|
826
901
|
};
|
|
827
902
|
|
|
828
|
-
|
|
829
|
-
// Get the write concern options
|
|
830
|
-
var finalOptions = writeConcern({}, self, options);
|
|
831
|
-
// Ensure we have a callback
|
|
832
|
-
if(finalOptions.writeConcern && typeof callback != 'function') {
|
|
833
|
-
throw new MongoError("Cannot use a writeConcern without a provided callback");
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
// Attempt to run using createIndexes command
|
|
837
|
-
createIndexUsingCreateIndexes(self, name, fieldOrSpec, options, function(err, result) {
|
|
838
|
-
if(err == null) return handleCallback(callback, err, result);
|
|
839
|
-
// Create command
|
|
840
|
-
var doc = createCreateIndexCommand(self, name, fieldOrSpec, options);
|
|
841
|
-
// Set no key checking
|
|
842
|
-
finalOptions.checkKeys = false;
|
|
843
|
-
// Insert document
|
|
844
|
-
self.s.topology.insert(f("%s.%s", self.s.databaseName, Db.SYSTEM_INDEX_COLLECTION), doc, finalOptions, function(err, result) {
|
|
845
|
-
if(callback == null) return;
|
|
846
|
-
if(err) return handleCallback(callback, err);
|
|
847
|
-
if(result == null) return handleCallback(callback, null, null);
|
|
848
|
-
if(result.result.writeErrors) return handleCallback(callback, MongoError.create(result.result.writeErrors[0]), null);
|
|
849
|
-
handleCallback(callback, null, doc.name);
|
|
850
|
-
});
|
|
851
|
-
});
|
|
852
|
-
}
|
|
903
|
+
define.classMethod('executeDbAdminCommand', {callback: true, promise:true});
|
|
853
904
|
|
|
854
905
|
/**
|
|
855
906
|
* Creates an index on the db and collection collection.
|
|
@@ -869,7 +920,7 @@ var createIndex = function(self, name, fieldOrSpec, options, callback) {
|
|
|
869
920
|
* @param {number} [options.v=null] Specify the format version of the indexes.
|
|
870
921
|
* @param {number} [options.expireAfterSeconds=null] Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
|
|
871
922
|
* @param {number} [options.name=null] Override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
|
|
872
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
923
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
873
924
|
* @return {Promise} returns Promise if no callback passed
|
|
874
925
|
*/
|
|
875
926
|
Db.prototype.createIndex = function(name, fieldOrSpec, options, callback) {
|
|
@@ -896,27 +947,37 @@ Db.prototype.createIndex = function(name, fieldOrSpec, options, callback) {
|
|
|
896
947
|
});
|
|
897
948
|
};
|
|
898
949
|
|
|
899
|
-
var
|
|
950
|
+
var createIndex = function(self, name, fieldOrSpec, options, callback) {
|
|
900
951
|
// Get the write concern options
|
|
901
952
|
var finalOptions = writeConcern({}, self, options);
|
|
902
|
-
//
|
|
903
|
-
|
|
904
|
-
|
|
953
|
+
// Ensure we have a callback
|
|
954
|
+
if(finalOptions.writeConcern && typeof callback != 'function') {
|
|
955
|
+
throw MongoError.create({message: "Cannot use a writeConcern without a provided callback", driver:true});
|
|
956
|
+
}
|
|
905
957
|
|
|
906
|
-
//
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
958
|
+
// Did the user destroy the topology
|
|
959
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
960
|
+
|
|
961
|
+
// Attempt to run using createIndexes command
|
|
962
|
+
createIndexUsingCreateIndexes(self, name, fieldOrSpec, options, function(err, result) {
|
|
963
|
+
if(err == null) return handleCallback(callback, err, result);
|
|
964
|
+
// Create command
|
|
965
|
+
var doc = createCreateIndexCommand(self, name, fieldOrSpec, options);
|
|
966
|
+
// Set no key checking
|
|
967
|
+
finalOptions.checkKeys = false;
|
|
968
|
+
// Insert document
|
|
969
|
+
self.s.topology.insert(f("%s.%s", self.s.databaseName, Db.SYSTEM_INDEX_COLLECTION), doc, finalOptions, function(err, result) {
|
|
970
|
+
if(callback == null) return;
|
|
971
|
+
if(err) return handleCallback(callback, err);
|
|
972
|
+
if(result == null) return handleCallback(callback, null, null);
|
|
973
|
+
if(result.result.writeErrors) return handleCallback(callback, MongoError.create(result.result.writeErrors[0]), null);
|
|
974
|
+
handleCallback(callback, null, doc.name);
|
|
975
|
+
});
|
|
976
|
+
});
|
|
918
977
|
}
|
|
919
978
|
|
|
979
|
+
define.classMethod('createIndex', {callback: true, promise:true});
|
|
980
|
+
|
|
920
981
|
/**
|
|
921
982
|
* Ensures that an index exists, if it does not it creates it
|
|
922
983
|
* @method
|
|
@@ -936,7 +997,7 @@ var ensureIndex = function(self, name, fieldOrSpec, options, callback) {
|
|
|
936
997
|
* @param {number} [options.v=null] Specify the format version of the indexes.
|
|
937
998
|
* @param {number} [options.expireAfterSeconds=null] Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
|
|
938
999
|
* @param {number} [options.name=null] Override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
|
|
939
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1000
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
940
1001
|
* @return {Promise} returns Promise if no callback passed
|
|
941
1002
|
*/
|
|
942
1003
|
Db.prototype.ensureIndex = function(name, fieldOrSpec, options, callback) {
|
|
@@ -946,7 +1007,7 @@ Db.prototype.ensureIndex = function(name, fieldOrSpec, options, callback) {
|
|
|
946
1007
|
|
|
947
1008
|
// If we have a callback fallback
|
|
948
1009
|
if(typeof callback == 'function') return ensureIndex(self, name, fieldOrSpec, options, callback);
|
|
949
|
-
|
|
1010
|
+
|
|
950
1011
|
// Return a promise
|
|
951
1012
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
952
1013
|
ensureIndex(self, name, fieldOrSpec, options, function(err, r) {
|
|
@@ -956,38 +1017,86 @@ Db.prototype.ensureIndex = function(name, fieldOrSpec, options, callback) {
|
|
|
956
1017
|
});
|
|
957
1018
|
};
|
|
958
1019
|
|
|
1020
|
+
var ensureIndex = function(self, name, fieldOrSpec, options, callback) {
|
|
1021
|
+
// Get the write concern options
|
|
1022
|
+
var finalOptions = writeConcern({}, self, options);
|
|
1023
|
+
// Create command
|
|
1024
|
+
var selector = createCreateIndexCommand(self, name, fieldOrSpec, options);
|
|
1025
|
+
var index_name = selector.name;
|
|
1026
|
+
|
|
1027
|
+
// Did the user destroy the topology
|
|
1028
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1029
|
+
|
|
1030
|
+
// Default command options
|
|
1031
|
+
var commandOptions = {};
|
|
1032
|
+
// Check if the index allready exists
|
|
1033
|
+
self.indexInformation(name, finalOptions, function(err, indexInformation) {
|
|
1034
|
+
if(err != null && err.code != 26) return handleCallback(callback, err, null);
|
|
1035
|
+
// If the index does not exist, create it
|
|
1036
|
+
if(indexInformation == null || !indexInformation[index_name]) {
|
|
1037
|
+
self.createIndex(name, fieldOrSpec, options, callback);
|
|
1038
|
+
} else {
|
|
1039
|
+
if(typeof callback === 'function') return handleCallback(callback, null, index_name);
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
define.classMethod('ensureIndex', {callback: true, promise:true});
|
|
1045
|
+
|
|
959
1046
|
Db.prototype.addChild = function(db) {
|
|
960
1047
|
if(this.s.parentDb) return this.s.parentDb.addChild(db);
|
|
961
1048
|
this.s.children.push(db);
|
|
962
1049
|
}
|
|
963
1050
|
|
|
964
1051
|
/**
|
|
965
|
-
* Create a new Db instance sharing the current socket connections.
|
|
1052
|
+
* Create a new Db instance sharing the current socket connections. Be aware that the new db instances are
|
|
1053
|
+
* related in a parent-child relationship to the original instance so that events are correctly emitted on child
|
|
1054
|
+
* db instances. Child db instances are cached so performing db('db1') twice will return the same instance.
|
|
1055
|
+
* You can control these behaviors with the options noListener and returnNonCachedInstance.
|
|
1056
|
+
*
|
|
966
1057
|
* @method
|
|
967
1058
|
* @param {string} name The name of the database we want to use.
|
|
1059
|
+
* @param {object} [options=null] Optional settings.
|
|
1060
|
+
* @param {boolean} [options.noListener=false] Do not make the db an event listener to the original connection.
|
|
1061
|
+
* @param {boolean} [options.returnNonCachedInstance=false] Control if you want to return a cached instance or have a new one created
|
|
968
1062
|
* @return {Db}
|
|
969
1063
|
*/
|
|
970
|
-
Db.prototype.db = function(dbName) {
|
|
1064
|
+
Db.prototype.db = function(dbName, options) {
|
|
1065
|
+
options = options || {};
|
|
971
1066
|
// Copy the options and add out internal override of the not shared flag
|
|
972
|
-
var options = {};
|
|
973
1067
|
for(var key in this.options) {
|
|
974
1068
|
options[key] = this.options[key];
|
|
975
1069
|
}
|
|
976
1070
|
|
|
1071
|
+
// Do we have the db in the cache already
|
|
1072
|
+
if(this.s.dbCache[dbName] && options.returnNonCachedInstance !== true) {
|
|
1073
|
+
return this.s.dbCache[dbName];
|
|
1074
|
+
}
|
|
1075
|
+
|
|
977
1076
|
// Add current db as parentDb
|
|
978
|
-
options.
|
|
1077
|
+
if(options.noListener == null || options.noListener == false) {
|
|
1078
|
+
options.parentDb = this;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
979
1081
|
// Add promiseLibrary
|
|
980
1082
|
options.promiseLibrary = this.s.promiseLibrary;
|
|
981
1083
|
|
|
982
1084
|
// Return the db object
|
|
983
1085
|
var db = new Db(dbName, this.s.topology, options)
|
|
1086
|
+
|
|
984
1087
|
// Add as child
|
|
985
|
-
|
|
986
|
-
|
|
1088
|
+
if(options.noListener == null || options.noListener == false) {
|
|
1089
|
+
this.addChild(db);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
// Add the db to the cache
|
|
1093
|
+
this.s.dbCache[dbName] = db;
|
|
987
1094
|
// Return the database
|
|
988
1095
|
return db;
|
|
989
1096
|
};
|
|
990
1097
|
|
|
1098
|
+
define.classMethod('db', {callback: false, promise:false, returns: [Db]});
|
|
1099
|
+
|
|
991
1100
|
var _executeAuthCreateUserCommand = function(self, username, password, options, callback) {
|
|
992
1101
|
// Special case where there is no password ($external users)
|
|
993
1102
|
if(typeof username == 'string'
|
|
@@ -1066,6 +1175,8 @@ var _executeAuthCreateUserCommand = function(self, username, password, options,
|
|
|
1066
1175
|
}
|
|
1067
1176
|
|
|
1068
1177
|
var addUser = function(self, username, password, options, callback) {
|
|
1178
|
+
// Did the user destroy the topology
|
|
1179
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1069
1180
|
// Attempt to execute auth command
|
|
1070
1181
|
_executeAuthCreateUserCommand(self, username, password, options, function(err, r) {
|
|
1071
1182
|
// We need to perform the backward compatible insert operation
|
|
@@ -1108,7 +1219,7 @@ var addUser = function(self, username, password, options, callback) {
|
|
|
1108
1219
|
|
|
1109
1220
|
if(err) return handleCallback(callback, err);
|
|
1110
1221
|
handleCallback(callback, err, r);
|
|
1111
|
-
});
|
|
1222
|
+
});
|
|
1112
1223
|
}
|
|
1113
1224
|
|
|
1114
1225
|
/**
|
|
@@ -1122,7 +1233,7 @@ var addUser = function(self, username, password, options, callback) {
|
|
|
1122
1233
|
* @param {boolean} [options.j=false] Specify a journal write concern.
|
|
1123
1234
|
* @param {object} [options.customData=null] Custom data associated with the user (only Mongodb 2.6 or higher)
|
|
1124
1235
|
* @param {object[]} [options.roles=null] Roles associated with the created user (only Mongodb 2.6 or higher)
|
|
1125
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1236
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
1126
1237
|
* @return {Promise} returns Promise if no callback passed
|
|
1127
1238
|
*/
|
|
1128
1239
|
Db.prototype.addUser = function(username, password, options, callback) {
|
|
@@ -1135,7 +1246,7 @@ Db.prototype.addUser = function(username, password, options, callback) {
|
|
|
1135
1246
|
|
|
1136
1247
|
// If we have a callback fallback
|
|
1137
1248
|
if(typeof callback == 'function') return addUser(self, username, password, options, callback);
|
|
1138
|
-
|
|
1249
|
+
|
|
1139
1250
|
// Return a promise
|
|
1140
1251
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1141
1252
|
addUser(self, username, password, options, function(err, r) {
|
|
@@ -1145,8 +1256,12 @@ Db.prototype.addUser = function(username, password, options, callback) {
|
|
|
1145
1256
|
});
|
|
1146
1257
|
};
|
|
1147
1258
|
|
|
1259
|
+
define.classMethod('addUser', {callback: true, promise:true});
|
|
1260
|
+
|
|
1148
1261
|
var _executeAuthRemoveUserCommand = function(self, username, options, callback) {
|
|
1149
1262
|
if(typeof options == 'function') callback = options, options = {};
|
|
1263
|
+
// Did the user destroy the topology
|
|
1264
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1150
1265
|
// Get the error options
|
|
1151
1266
|
var commandOptions = {writeCommand:true};
|
|
1152
1267
|
if(options['dbName']) commandOptions.dbName = options['dbName'];
|
|
@@ -1200,9 +1315,11 @@ var removeUser = function(self, username, options, callback) {
|
|
|
1200
1315
|
|
|
1201
1316
|
if(err) return handleCallback(callback, err);
|
|
1202
1317
|
handleCallback(callback, err, result);
|
|
1203
|
-
});
|
|
1318
|
+
});
|
|
1204
1319
|
}
|
|
1205
1320
|
|
|
1321
|
+
define.classMethod('removeUser', {callback: true, promise:true});
|
|
1322
|
+
|
|
1206
1323
|
/**
|
|
1207
1324
|
* Remove a user from a database
|
|
1208
1325
|
* @method
|
|
@@ -1211,7 +1328,7 @@ var removeUser = function(self, username, options, callback) {
|
|
|
1211
1328
|
* @param {(number|string)} [options.w=null] The write concern.
|
|
1212
1329
|
* @param {number} [options.wtimeout=null] The write concern timeout.
|
|
1213
1330
|
* @param {boolean} [options.j=false] Specify a journal write concern.
|
|
1214
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1331
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
1215
1332
|
* @return {Promise} returns Promise if no callback passed
|
|
1216
1333
|
*/
|
|
1217
1334
|
Db.prototype.removeUser = function(username, options, callback) {
|
|
@@ -1235,6 +1352,8 @@ Db.prototype.removeUser = function(username, options, callback) {
|
|
|
1235
1352
|
};
|
|
1236
1353
|
|
|
1237
1354
|
var authenticate = function(self, username, password, options, callback) {
|
|
1355
|
+
// Did the user destroy the topology
|
|
1356
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1238
1357
|
// the default db to authenticate against is 'self'
|
|
1239
1358
|
// if authententicate is called from a retry context, it may be another one, like admin
|
|
1240
1359
|
var authdb = options.authdb ? options.authdb : options.dbName;
|
|
@@ -1294,7 +1413,7 @@ var authenticate = function(self, username, password, options, callback) {
|
|
|
1294
1413
|
_callback(null, true);
|
|
1295
1414
|
});
|
|
1296
1415
|
} else {
|
|
1297
|
-
handleCallback(callback,
|
|
1416
|
+
handleCallback(callback, MongoError.create({message: f("authentication mechanism %s not supported", options.authMechanism), driver:true}));
|
|
1298
1417
|
}
|
|
1299
1418
|
}
|
|
1300
1419
|
|
|
@@ -1305,7 +1424,7 @@ var authenticate = function(self, username, password, options, callback) {
|
|
|
1305
1424
|
* @param {string} [password] The password.
|
|
1306
1425
|
* @param {object} [options=null] Optional settings.
|
|
1307
1426
|
* @param {string} [options.authMechanism=MONGODB-CR] The authentication mechanism to use, GSSAPI, MONGODB-CR, MONGODB-X509, PLAIN
|
|
1308
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1427
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
1309
1428
|
* @return {Promise} returns Promise if no callback passed
|
|
1310
1429
|
*/
|
|
1311
1430
|
Db.prototype.authenticate = function(username, password, options, callback) {
|
|
@@ -1322,27 +1441,38 @@ Db.prototype.authenticate = function(username, password, options, callback) {
|
|
|
1322
1441
|
&& options.authMechanism != 'MONGODB-X509'
|
|
1323
1442
|
&& options.authMechanism != 'SCRAM-SHA-1'
|
|
1324
1443
|
&& options.authMechanism != 'PLAIN') {
|
|
1325
|
-
return handleCallback(callback,
|
|
1444
|
+
return handleCallback(callback, MongoError.create({message: "only GSSAPI, PLAIN, MONGODB-X509, SCRAM-SHA-1 or MONGODB-CR is supported by authMechanism", driver:true}));
|
|
1326
1445
|
}
|
|
1327
1446
|
|
|
1328
1447
|
// If we have a callback fallback
|
|
1329
|
-
if(typeof callback == 'function') return authenticate(self, username, password, options,
|
|
1330
|
-
|
|
1448
|
+
if(typeof callback == 'function') return authenticate(self, username, password, options, function(err, r) {
|
|
1449
|
+
// Support failed auth method
|
|
1450
|
+
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
1451
|
+
// Reject error
|
|
1452
|
+
if(err) return callback(err, r);
|
|
1453
|
+
callback(null, r);
|
|
1454
|
+
});
|
|
1455
|
+
|
|
1331
1456
|
// Return a promise
|
|
1332
1457
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1333
1458
|
authenticate(self, username, password, options, function(err, r) {
|
|
1459
|
+
// Support failed auth method
|
|
1460
|
+
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
1461
|
+
// Reject error
|
|
1334
1462
|
if(err) return reject(err);
|
|
1335
1463
|
resolve(r);
|
|
1336
1464
|
});
|
|
1337
1465
|
});
|
|
1338
1466
|
};
|
|
1339
1467
|
|
|
1468
|
+
define.classMethod('authenticate', {callback: true, promise:true});
|
|
1469
|
+
|
|
1340
1470
|
/**
|
|
1341
1471
|
* Logout user from server, fire off on all connections and remove all auth info
|
|
1342
1472
|
* @method
|
|
1343
1473
|
* @param {object} [options=null] Optional settings.
|
|
1344
1474
|
* @param {string} [options.dbName=null] Logout against different database than current.
|
|
1345
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1475
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
1346
1476
|
* @return {Promise} returns Promise if no callback passed
|
|
1347
1477
|
*/
|
|
1348
1478
|
Db.prototype.logout = function(options, callback) {
|
|
@@ -1363,6 +1493,8 @@ Db.prototype.logout = function(options, callback) {
|
|
|
1363
1493
|
|
|
1364
1494
|
// Execute the command
|
|
1365
1495
|
if(typeof callback == 'function') return this.command(cmd, options, function(err, result) {
|
|
1496
|
+
// Did the user destroy the topology
|
|
1497
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1366
1498
|
if(err) return handleCallback(callback, err, false);
|
|
1367
1499
|
handleCallback(callback, null, true)
|
|
1368
1500
|
});
|
|
@@ -1370,12 +1502,16 @@ Db.prototype.logout = function(options, callback) {
|
|
|
1370
1502
|
// Return promise
|
|
1371
1503
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1372
1504
|
self.command(cmd, options, function(err, result) {
|
|
1505
|
+
// Did the user destroy the topology
|
|
1506
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return reject(new MongoError('topology was destroyed'));
|
|
1373
1507
|
if(err) return reject(err);
|
|
1374
1508
|
resolve(true);
|
|
1375
1509
|
});
|
|
1376
1510
|
});
|
|
1377
1511
|
}
|
|
1378
1512
|
|
|
1513
|
+
define.classMethod('logout', {callback: true, promise:true});
|
|
1514
|
+
|
|
1379
1515
|
// Figure out the read preference
|
|
1380
1516
|
var getReadPreference = function(options, db) {
|
|
1381
1517
|
if(options.readPreference) return options;
|
|
@@ -1390,7 +1526,7 @@ var getReadPreference = function(options, db) {
|
|
|
1390
1526
|
* @param {object} [options=null] Optional settings.
|
|
1391
1527
|
* @param {boolean} [options.full=false] Returns the full raw index information.
|
|
1392
1528
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
1393
|
-
* @param {Db~resultCallback} callback The command result callback
|
|
1529
|
+
* @param {Db~resultCallback} [callback] The command result callback
|
|
1394
1530
|
* @return {Promise} returns Promise if no callback passed
|
|
1395
1531
|
*/
|
|
1396
1532
|
Db.prototype.indexInformation = function(name, options, callback) {
|
|
@@ -1400,7 +1536,7 @@ Db.prototype.indexInformation = function(name, options, callback) {
|
|
|
1400
1536
|
|
|
1401
1537
|
// If we have a callback fallback
|
|
1402
1538
|
if(typeof callback == 'function') return indexInformation(self, name, options, callback);
|
|
1403
|
-
|
|
1539
|
+
|
|
1404
1540
|
// Return a promise
|
|
1405
1541
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1406
1542
|
indexInformation(self, name, options, function(err, r) {
|
|
@@ -1414,6 +1550,9 @@ var indexInformation = function(self, name, options, callback) {
|
|
|
1414
1550
|
// If we specified full information
|
|
1415
1551
|
var full = options['full'] == null ? false : options['full'];
|
|
1416
1552
|
|
|
1553
|
+
// Did the user destroy the topology
|
|
1554
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1555
|
+
|
|
1417
1556
|
// Process all the results from the index command and collection
|
|
1418
1557
|
var processResults = function(indexes) {
|
|
1419
1558
|
// Contains all the information
|
|
@@ -1440,6 +1579,8 @@ var indexInformation = function(self, name, options, callback) {
|
|
|
1440
1579
|
});
|
|
1441
1580
|
}
|
|
1442
1581
|
|
|
1582
|
+
define.classMethod('indexInformation', {callback: true, promise:true});
|
|
1583
|
+
|
|
1443
1584
|
var createCreateIndexCommand = function(db, name, fieldOrSpec, options) {
|
|
1444
1585
|
var indexParameters = parseIndexOptions(fieldOrSpec);
|
|
1445
1586
|
var fieldHash = indexParameters.fieldHash;
|
|
@@ -1514,13 +1655,13 @@ var createIndexUsingCreateIndexes = function(self, name, fieldOrSpec, options, c
|
|
|
1514
1655
|
|
|
1515
1656
|
// Validate the database name
|
|
1516
1657
|
var validateDatabaseName = function(databaseName) {
|
|
1517
|
-
if(typeof databaseName !== 'string') throw
|
|
1518
|
-
if(databaseName.length === 0) throw
|
|
1658
|
+
if(typeof databaseName !== 'string') throw MongoError.create({message: "database name must be a string", driver:true});
|
|
1659
|
+
if(databaseName.length === 0) throw MongoError.create({message: "database name cannot be the empty string", driver:true});
|
|
1519
1660
|
if(databaseName == '$external') return;
|
|
1520
1661
|
|
|
1521
1662
|
var invalidChars = [" ", ".", "$", "/", "\\"];
|
|
1522
1663
|
for(var i = 0; i < invalidChars.length; i++) {
|
|
1523
|
-
if(databaseName.indexOf(invalidChars[i]) != -1) throw
|
|
1664
|
+
if(databaseName.indexOf(invalidChars[i]) != -1) throw MongoError.create({message: "database names cannot contain the character '" + invalidChars[i] + "'", driver:true});
|
|
1524
1665
|
}
|
|
1525
1666
|
}
|
|
1526
1667
|
|
|
@@ -1558,13 +1699,17 @@ var createListener = function(self, e, object) {
|
|
|
1558
1699
|
/**
|
|
1559
1700
|
* Db close event
|
|
1560
1701
|
*
|
|
1702
|
+
* Emitted after a socket closed against a single server or mongos proxy.
|
|
1703
|
+
*
|
|
1561
1704
|
* @event Db#close
|
|
1562
|
-
* @type {
|
|
1705
|
+
* @type {MongoError}
|
|
1563
1706
|
*/
|
|
1564
1707
|
|
|
1565
1708
|
/**
|
|
1566
1709
|
* Db authenticated event
|
|
1567
1710
|
*
|
|
1711
|
+
* Emitted after all server members in the topology (single server, replicaset or mongos) have successfully authenticated.
|
|
1712
|
+
*
|
|
1568
1713
|
* @event Db#authenticated
|
|
1569
1714
|
* @type {object}
|
|
1570
1715
|
*/
|
|
@@ -1572,6 +1717,10 @@ var createListener = function(self, e, object) {
|
|
|
1572
1717
|
/**
|
|
1573
1718
|
* Db reconnect event
|
|
1574
1719
|
*
|
|
1720
|
+
* * Server: Emitted when the driver has reconnected and re-authenticated.
|
|
1721
|
+
* * ReplicaSet: N/A
|
|
1722
|
+
* * Mongos: Emitted when the driver reconnects and re-authenticates successfully against a Mongos.
|
|
1723
|
+
*
|
|
1575
1724
|
* @event Db#reconnect
|
|
1576
1725
|
* @type {object}
|
|
1577
1726
|
*/
|
|
@@ -1579,6 +1728,8 @@ var createListener = function(self, e, object) {
|
|
|
1579
1728
|
/**
|
|
1580
1729
|
* Db error event
|
|
1581
1730
|
*
|
|
1731
|
+
* Emitted after an error occurred against a single server or mongos proxy.
|
|
1732
|
+
*
|
|
1582
1733
|
* @event Db#error
|
|
1583
1734
|
* @type {MongoError}
|
|
1584
1735
|
*/
|
|
@@ -1586,19 +1737,27 @@ var createListener = function(self, e, object) {
|
|
|
1586
1737
|
/**
|
|
1587
1738
|
* Db timeout event
|
|
1588
1739
|
*
|
|
1740
|
+
* Emitted after a socket timeout occurred against a single server or mongos proxy.
|
|
1741
|
+
*
|
|
1589
1742
|
* @event Db#timeout
|
|
1590
|
-
* @type {
|
|
1743
|
+
* @type {MongoError}
|
|
1591
1744
|
*/
|
|
1592
1745
|
|
|
1593
1746
|
/**
|
|
1594
1747
|
* Db parseError event
|
|
1595
1748
|
*
|
|
1749
|
+
* The parseError event is emitted if the driver detects illegal or corrupt BSON being received from the server.
|
|
1750
|
+
*
|
|
1596
1751
|
* @event Db#parseError
|
|
1597
|
-
* @type {
|
|
1752
|
+
* @type {MongoError}
|
|
1598
1753
|
*/
|
|
1599
1754
|
|
|
1600
1755
|
/**
|
|
1601
|
-
* Db fullsetup event, emitted when all servers in the topology have been connected to.
|
|
1756
|
+
* Db fullsetup event, emitted when all servers in the topology have been connected to at start up time.
|
|
1757
|
+
*
|
|
1758
|
+
* * Server: Emitted when the driver has connected to the single server and has authenticated.
|
|
1759
|
+
* * ReplSet: Emitted after the driver has attempted to connect to all replicaset members.
|
|
1760
|
+
* * Mongos: Emitted after the driver has attempted to connect to all mongos proxies.
|
|
1602
1761
|
*
|
|
1603
1762
|
* @event Db#fullsetup
|
|
1604
1763
|
* @type {Db}
|