mongodb 1.3.14 → 1.3.19
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/Readme.md +1 -1
- package/lib/mongodb/collection.js +9 -6
- package/lib/mongodb/connection/base.js +38 -25
- package/lib/mongodb/connection/repl_set/repl_set.js +27 -49
- package/lib/mongodb/connection/server.js +8 -1
- package/lib/mongodb/cursor.js +0 -2
- package/lib/mongodb/db.js +28 -5
- package/lib/mongodb/gridfs/gridstore.js +1 -1
- package/lib/mongodb/mongo_client.js +57 -9
- package/lib/mongodb/responses/mongo_reply.js +21 -88
- package/package.json +1 -1
- package/t.js +147 -0
- package/install.js +0 -40
package/Readme.md
CHANGED
|
@@ -131,7 +131,7 @@ For more information have a look at [Gridstore](https://github.com/mongodb/node-
|
|
|
131
131
|
|
|
132
132
|
Replicasets
|
|
133
133
|
===========
|
|
134
|
-
For more information about how to connect to a replicaset have a look at [
|
|
134
|
+
For more information about how to connect to a replicaset have a look at the extensive documentation [Documentation](http://mongodb.github.com/node-mongodb-native/)
|
|
135
135
|
|
|
136
136
|
Primary Key Factories
|
|
137
137
|
---------------------
|
|
@@ -583,13 +583,16 @@ Collection.prototype.count = function count (query, options, callback) {
|
|
|
583
583
|
if(typeof limit == 'number') commandObject.limit = limit;
|
|
584
584
|
|
|
585
585
|
// Set read preference if we set one
|
|
586
|
-
|
|
586
|
+
var readPreference = _getReadConcern(this, options);
|
|
587
587
|
|
|
588
588
|
// Execute the command
|
|
589
|
-
this.db.
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
589
|
+
this.db._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this.db, commandObject)
|
|
590
|
+
, {read: readPreference}
|
|
591
|
+
, utils.handleSingleCommandResultReturn(null, null, function(err, result) {
|
|
592
|
+
if(err) return callback(err, null);
|
|
593
|
+
if(result == null) return callback(new Error("no result returned for count"), null);
|
|
594
|
+
callback(null, result.n);
|
|
595
|
+
}));
|
|
593
596
|
};
|
|
594
597
|
|
|
595
598
|
|
|
@@ -667,7 +670,7 @@ Collection.prototype.findAndModify = function findAndModify (query, sort, doc, o
|
|
|
667
670
|
this.db._executeQueryCommand(command
|
|
668
671
|
, {read:false}, utils.handleSingleCommandResultReturn(null, null, function(err, result) {
|
|
669
672
|
if(err) return callback(err, null);
|
|
670
|
-
return callback(null, result.value, result
|
|
673
|
+
return callback(null, result.value, result);
|
|
671
674
|
}));
|
|
672
675
|
}
|
|
673
676
|
|
|
@@ -195,33 +195,33 @@ DbStore.prototype.fetch = function(databaseName) {
|
|
|
195
195
|
DbStore.prototype.emit = function(event, message, object, reset, filterDb, rethrow_if_no_listeners) {
|
|
196
196
|
var emitted = false;
|
|
197
197
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
db.emit(event, message, object == null ? db : object);
|
|
206
|
-
emitted = true;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
for(var i = 0; i < this._dbs.length; i++) {
|
|
212
|
-
if(this._dbs[i].listeners(event).length > 0) {
|
|
213
|
-
if(filterDb == null || filterDb.databaseName !== this._dbs[i].databaseName
|
|
214
|
-
|| filterDb.tag !== this._dbs[i].tag) {
|
|
215
|
-
this._dbs[i].emit(event, message, object == null ? this._dbs[i] : object);
|
|
216
|
-
emitted = true;
|
|
217
|
-
}
|
|
198
|
+
// Emit the events
|
|
199
|
+
for(var i = 0; i < this._dbs.length; i++) {
|
|
200
|
+
if(this._dbs[i].listeners(event).length > 0) {
|
|
201
|
+
if(filterDb == null || filterDb.databaseName !== this._dbs[i].databaseName
|
|
202
|
+
|| filterDb.tag !== this._dbs[i].tag) {
|
|
203
|
+
this._dbs[i].emit(event, message, object == null ? this._dbs[i] : object);
|
|
204
|
+
emitted = true;
|
|
218
205
|
}
|
|
219
206
|
}
|
|
220
207
|
}
|
|
221
208
|
|
|
209
|
+
// Emit error message
|
|
210
|
+
if(message
|
|
211
|
+
&& event == 'error'
|
|
212
|
+
&& !emitted
|
|
213
|
+
&& rethrow_if_no_listeners
|
|
214
|
+
&& object && object.db) {
|
|
215
|
+
process.nextTick(function() {
|
|
216
|
+
object.db.emit(event, message, null);
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
|
|
222
220
|
// Not emitted and we have enabled rethrow, let process.uncaughtException
|
|
223
221
|
// deal with the issue
|
|
224
|
-
if(!emitted && rethrow_if_no_listeners)
|
|
222
|
+
if(!emitted && rethrow_if_no_listeners) {
|
|
223
|
+
throw message;
|
|
224
|
+
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
var Base = function Base() {
|
|
@@ -288,6 +288,10 @@ Base.prototype.__executeAllCallbacksWithError = function(err) {
|
|
|
288
288
|
this._callBackStore.emit(keys[j], err, null);
|
|
289
289
|
// Remove the key
|
|
290
290
|
delete this._callBackStore._notReplied[keys[j]];
|
|
291
|
+
// Force cleanup _events, node.js seems to set it as a null value
|
|
292
|
+
if(this._callBackStore._events) {
|
|
293
|
+
delete this._callBackStore._events[keys[j]];
|
|
294
|
+
}
|
|
291
295
|
}
|
|
292
296
|
}
|
|
293
297
|
|
|
@@ -311,6 +315,10 @@ Base.prototype.__executeAllServerSpecificErrorCallbacks = function(host, port, e
|
|
|
311
315
|
this._callBackStore.emit(keys[j], err, null);
|
|
312
316
|
// Remove the key
|
|
313
317
|
delete this._callBackStore._notReplied[keys[j]];
|
|
318
|
+
// Force cleanup _events, node.js seems to set it as a null value
|
|
319
|
+
if(this._callBackStore._events) {
|
|
320
|
+
delete this._callBackStore._events[keys[j]];
|
|
321
|
+
}
|
|
314
322
|
}
|
|
315
323
|
}
|
|
316
324
|
}
|
|
@@ -364,10 +372,14 @@ Base.prototype._callHandler = function(id, document, err) {
|
|
|
364
372
|
var callback = this._callBackStore.listeners(id)[0].listener;
|
|
365
373
|
// Remove the listeners
|
|
366
374
|
this._callBackStore.removeAllListeners(id);
|
|
375
|
+
// Force key deletion because it nulling it not deleting in 0.10.X
|
|
376
|
+
if(this._callBackStore._events) {
|
|
377
|
+
delete this._callBackStore._events[id];
|
|
378
|
+
}
|
|
367
379
|
|
|
368
|
-
// Execute the callback
|
|
369
380
|
try {
|
|
370
|
-
callback
|
|
381
|
+
// Execute the callback if one was provided
|
|
382
|
+
if(typeof callback == 'function') callback(err, document, info.connection);
|
|
371
383
|
} catch(err) {
|
|
372
384
|
self._emitAcrossAllDbInstances(self, null, "error", err, self, true, true);
|
|
373
385
|
}
|
|
@@ -380,7 +392,6 @@ Base.prototype._callHandler = function(id, document, err) {
|
|
|
380
392
|
* @api private
|
|
381
393
|
*/
|
|
382
394
|
Base.prototype._hasHandler = function(id) {
|
|
383
|
-
// If there is a callback peform it
|
|
384
395
|
return this._callBackStore.listeners(id).length >= 1;
|
|
385
396
|
}
|
|
386
397
|
|
|
@@ -395,7 +406,9 @@ Base.prototype._removeHandler = function(id) {
|
|
|
395
406
|
// Remove the callback if it's registered
|
|
396
407
|
this._callBackStore.removeAllListeners(id);
|
|
397
408
|
// Force cleanup _events, node.js seems to set it as a null value
|
|
398
|
-
if(this._callBackStore._events
|
|
409
|
+
if(this._callBackStore._events) {
|
|
410
|
+
delete this._callBackStore._events[id];
|
|
411
|
+
}
|
|
399
412
|
}
|
|
400
413
|
|
|
401
414
|
/**
|
|
@@ -50,7 +50,8 @@ var processor = require('../../utils').processor();
|
|
|
50
50
|
* - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
|
|
51
51
|
* - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher)
|
|
52
52
|
*
|
|
53
|
-
* @class Represents a
|
|
53
|
+
* @class Represents a
|
|
54
|
+
Replicaset Configuration
|
|
54
55
|
* @param {Array} list of server objects participating in the replicaset.
|
|
55
56
|
* @param {Object} [options] additional options for the replicaset connection.
|
|
56
57
|
*/
|
|
@@ -370,11 +371,27 @@ var locateNewServers = function(self, state, candidateServers, ismaster) {
|
|
|
370
371
|
var _connectHandler = function(self, candidateServers, instanceServer) {
|
|
371
372
|
return function(err, doc) {
|
|
372
373
|
// If we have an error add to the list
|
|
373
|
-
if(err)
|
|
374
|
+
if(err) {
|
|
375
|
+
self._state.errors[instanceServer.name] = instanceServer;
|
|
376
|
+
} else {
|
|
377
|
+
delete self._state.errors[instanceServer.name];
|
|
378
|
+
}
|
|
374
379
|
|
|
375
|
-
// No error let's analyse the ismaster command
|
|
376
380
|
if(!err) {
|
|
377
381
|
var ismaster = doc.documents[0]
|
|
382
|
+
|
|
383
|
+
// Error the server if
|
|
384
|
+
if(!ismaster.ismaster
|
|
385
|
+
&& !ismaster.secondary) {
|
|
386
|
+
self._state.errors[instanceServer.name] = instanceServer;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
// No error let's analyse the ismaster command
|
|
392
|
+
if(!err && self._state.errors[instanceServer.name] == null) {
|
|
393
|
+
var ismaster = doc.documents[0]
|
|
394
|
+
|
|
378
395
|
// If no replicaset name exists set the current one
|
|
379
396
|
if(self.options.rs_name == null) {
|
|
380
397
|
self.options.rs_name = ismaster.setName;
|
|
@@ -402,9 +419,11 @@ var _connectHandler = function(self, candidateServers, instanceServer) {
|
|
|
402
419
|
// Get additional new servers that are not currently in set
|
|
403
420
|
var new_servers = locateNewServers(self, self._state, candidateServers, ismaster);
|
|
404
421
|
|
|
405
|
-
//
|
|
406
|
-
|
|
407
|
-
|
|
422
|
+
// Locate any new servers that have not errored out yet
|
|
423
|
+
for(var i = 0; i < new_servers.length; i++) {
|
|
424
|
+
if(self._state.errors[new_servers[i].name] == null) {
|
|
425
|
+
candidateServers.push(new_servers[i])
|
|
426
|
+
}
|
|
408
427
|
}
|
|
409
428
|
}
|
|
410
429
|
}
|
|
@@ -465,55 +484,14 @@ ReplSet.prototype.checkoutWriter = function() {
|
|
|
465
484
|
return new Error("no writer connection available");
|
|
466
485
|
}
|
|
467
486
|
|
|
468
|
-
// var _handler = function(event, self, server) {
|
|
469
|
-
// return function(err, doc) {
|
|
470
|
-
// // The event happened to a primary
|
|
471
|
-
// // Remove it from play
|
|
472
|
-
// if(self._state.isPrimary(server)) {
|
|
473
|
-
// var current_master = self._state.master;
|
|
474
|
-
// self._state.master = null;
|
|
475
|
-
// self._serverState = ReplSet.REPLSET_READ_ONLY;
|
|
476
|
-
|
|
477
|
-
// if(current_master != null) {
|
|
478
|
-
// // Unpack variables
|
|
479
|
-
// var host = current_master.socketOptions.host;
|
|
480
|
-
// var port = current_master.socketOptions.port;
|
|
481
|
-
|
|
482
|
-
// // Fire error on any unknown callbacks
|
|
483
|
-
// self.__executeAllServerSpecificErrorCallbacks(host, port, err);
|
|
484
|
-
// }
|
|
485
|
-
// } else if(self._state.isSecondary(server)) {
|
|
486
|
-
// delete self._state.secondaries[server.name];
|
|
487
|
-
// }
|
|
488
|
-
|
|
489
|
-
// // If there is no more connections left and the setting is not destroyed
|
|
490
|
-
// // set to disconnected
|
|
491
|
-
// if(Object.keys(self._state.addresses).length == 0
|
|
492
|
-
// && self._serverState != ReplSet.REPLSET_DESTROYED) {
|
|
493
|
-
// self._serverState = ReplSet.REPLSET_DISCONNECTED;
|
|
494
|
-
|
|
495
|
-
// // Emit close across all the attached db instances
|
|
496
|
-
// self._dbStore.emit("close", new Error("replicaset disconnected, no valid servers contactable over tcp"), null, true);
|
|
497
|
-
// }
|
|
498
|
-
|
|
499
|
-
// // Unpack variables
|
|
500
|
-
// var host = server.socketOptions.host;
|
|
501
|
-
// var port = server.socketOptions.port;
|
|
502
|
-
|
|
503
|
-
// // Fire error on any unknown callbacks
|
|
504
|
-
// self.__executeAllServerSpecificErrorCallbacks(host, port, err);
|
|
505
|
-
// }
|
|
506
|
-
// }
|
|
507
|
-
|
|
508
487
|
ReplSet.prototype.processIsMaster = function(_server, _ismaster) {
|
|
509
488
|
// Server in recovery mode, remove it from available servers
|
|
510
489
|
if(!_ismaster.ismaster && !_ismaster.secondary) {
|
|
511
490
|
// Locate the actual server
|
|
512
|
-
var server = this.
|
|
491
|
+
var server = this._state.addresses[_server.name];
|
|
513
492
|
// Close the server, simulating the closing of the connection
|
|
514
493
|
// to get right removal semantics
|
|
515
|
-
if(server)
|
|
516
|
-
server.close();
|
|
494
|
+
if(server) server.close();
|
|
517
495
|
// Execute any callback errors
|
|
518
496
|
_handler(null, this, server)(new Error("server is in recovery mode"));
|
|
519
497
|
}
|
|
@@ -5,6 +5,7 @@ var Connection = require('./connection').Connection,
|
|
|
5
5
|
ConnectionPool = require('./connection_pool').ConnectionPool,
|
|
6
6
|
EventEmitter = require('events').EventEmitter,
|
|
7
7
|
Base = require('./base').Base,
|
|
8
|
+
format = require('util').format,
|
|
8
9
|
utils = require('../utils'),
|
|
9
10
|
timers = require('timers'),
|
|
10
11
|
inherits = require('util').inherits;
|
|
@@ -73,6 +74,8 @@ function Server(host, port, options) {
|
|
|
73
74
|
this.sslKey = this.options.sslKey;
|
|
74
75
|
// Password to unlock private key
|
|
75
76
|
this.sslPass = this.options.sslPass;
|
|
77
|
+
// Set server name
|
|
78
|
+
this.name = format("%s:%s", host, port);
|
|
76
79
|
|
|
77
80
|
// Ensure we are not trying to validate with no list of certificates
|
|
78
81
|
if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) {
|
|
@@ -365,8 +368,12 @@ Server.prototype.connect = function(dbInstance, options, callback) {
|
|
|
365
368
|
// Save document returned so we can query it
|
|
366
369
|
_server.isMasterDoc = reply.documents[0];
|
|
367
370
|
|
|
368
|
-
if(self.emitOpen)
|
|
371
|
+
if(self.emitOpen) {
|
|
369
372
|
_server._emitAcrossAllDbInstances(_server, eventReceiver, "open", null, returnIsMasterResults ? reply : null, null);
|
|
373
|
+
self.emitOpen = false;
|
|
374
|
+
} else {
|
|
375
|
+
_server._emitAcrossAllDbInstances(_server, eventReceiver, "reconnect", null, returnIsMasterResults ? reply : null, null);
|
|
376
|
+
}
|
|
370
377
|
|
|
371
378
|
// If we have it set to returnIsMasterResults
|
|
372
379
|
if(returnIsMasterResults) {
|
package/lib/mongodb/cursor.js
CHANGED
|
@@ -662,8 +662,6 @@ Cursor.prototype.nextObject = function(options, callback) {
|
|
|
662
662
|
// If we have no connection set on this cursor check one out
|
|
663
663
|
if(self.connection == null) {
|
|
664
664
|
try {
|
|
665
|
-
// self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read);
|
|
666
|
-
// console.log("++++++++++++++++++++++++++++++ checkoutReader :: CURSOR")
|
|
667
665
|
self.connection = self.db.serverConfig.checkoutReader(this.read);
|
|
668
666
|
// Add to the query options
|
|
669
667
|
queryOptions.connection = self.connection;
|
package/lib/mongodb/db.js
CHANGED
|
@@ -271,10 +271,22 @@ Db.prototype.open = function(callback) {
|
|
|
271
271
|
// If we have queued up commands execute a command to trigger replays
|
|
272
272
|
if(self.commands.length > 0) _execute_queued_command(self);
|
|
273
273
|
// Callback
|
|
274
|
-
|
|
274
|
+
process.nextTick(function() {
|
|
275
|
+
try {
|
|
276
|
+
callback(null, self);
|
|
277
|
+
} catch(err) {
|
|
278
|
+
self.close();
|
|
279
|
+
throw err;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
275
282
|
});
|
|
276
283
|
} else {
|
|
277
|
-
|
|
284
|
+
try {
|
|
285
|
+
callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null);
|
|
286
|
+
} catch(err) {
|
|
287
|
+
self.close();
|
|
288
|
+
throw err;
|
|
289
|
+
}
|
|
278
290
|
}
|
|
279
291
|
};
|
|
280
292
|
|
|
@@ -873,6 +885,12 @@ Db.prototype.createCollection = function(collectionName, options, callback) {
|
|
|
873
885
|
});
|
|
874
886
|
};
|
|
875
887
|
|
|
888
|
+
var _getReadConcern = function(self, options) {
|
|
889
|
+
if(options.readPreference) return options.readPreference;
|
|
890
|
+
if(self.readPreference) return self.readPreference;
|
|
891
|
+
return 'primary';
|
|
892
|
+
}
|
|
893
|
+
|
|
876
894
|
/**
|
|
877
895
|
* Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server.
|
|
878
896
|
*
|
|
@@ -915,8 +933,12 @@ Db.prototype.command = function(selector, options, callback) {
|
|
|
915
933
|
cursor.setReadPreference(readPreference);
|
|
916
934
|
}
|
|
917
935
|
|
|
918
|
-
//
|
|
919
|
-
cursor.nextObject(
|
|
936
|
+
// Get the next result
|
|
937
|
+
cursor.nextObject(function(err, result) {
|
|
938
|
+
if(err) return callback(err, null);
|
|
939
|
+
if(result == null) return callback(new Error("no result returned from command"), null);
|
|
940
|
+
callback(null, result);
|
|
941
|
+
});
|
|
920
942
|
};
|
|
921
943
|
|
|
922
944
|
/**
|
|
@@ -1598,7 +1620,8 @@ Db.prototype._executeQueryCommand = function(db_command, options, callback) {
|
|
|
1598
1620
|
}
|
|
1599
1621
|
}
|
|
1600
1622
|
|
|
1601
|
-
if(this.serverConfig.isDestroyed())
|
|
1623
|
+
if(this.serverConfig.isDestroyed())
|
|
1624
|
+
return callback(new Error("Connection was destroyed by application"));
|
|
1602
1625
|
|
|
1603
1626
|
// Specific connection
|
|
1604
1627
|
var connection = options.connection;
|
|
@@ -1151,7 +1151,7 @@ GridStore.unlink = function(db, names, options, callback) {
|
|
|
1151
1151
|
var tc = 0;
|
|
1152
1152
|
for(var i = 0; i < names.length; i++) {
|
|
1153
1153
|
++tc;
|
|
1154
|
-
self.unlink(db, names[i], function(result) {
|
|
1154
|
+
self.unlink(db, names[i], options, function(result) {
|
|
1155
1155
|
if(--tc == 0) {
|
|
1156
1156
|
callback(null, self);
|
|
1157
1157
|
}
|
|
@@ -151,7 +151,7 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
151
151
|
callback = typeof args[args.length - 1] == 'function' ? args.pop() : null;
|
|
152
152
|
options = args.length ? args.shift() : null;
|
|
153
153
|
options = options || {};
|
|
154
|
-
|
|
154
|
+
|
|
155
155
|
// Set default empty server options
|
|
156
156
|
var serverOptions = options.server || {};
|
|
157
157
|
var mongosOptions = options.mongos || {};
|
|
@@ -159,7 +159,8 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
159
159
|
var dbOptions = options.db || {};
|
|
160
160
|
|
|
161
161
|
// If callback is null throw an exception
|
|
162
|
-
if(callback == null)
|
|
162
|
+
if(callback == null)
|
|
163
|
+
throw new Error("no callback function provided");
|
|
163
164
|
|
|
164
165
|
// Parse the string
|
|
165
166
|
var object = parse(url, options);
|
|
@@ -252,8 +253,16 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
252
253
|
|
|
253
254
|
if(totalNumberOfServers == 0) {
|
|
254
255
|
// If we have a mix of mongod and mongos, throw an error
|
|
255
|
-
if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0)
|
|
256
|
-
return
|
|
256
|
+
if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) {
|
|
257
|
+
return process.nextTick(function() {
|
|
258
|
+
try {
|
|
259
|
+
callback(new Error("cannot combine a list of replicaset seeds and mongos seeds"));
|
|
260
|
+
} catch (err) {
|
|
261
|
+
if(db) db.close();
|
|
262
|
+
throw err
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
}
|
|
257
266
|
|
|
258
267
|
if(totalNumberOfMongodServers == 0 && object.servers.length == 1) {
|
|
259
268
|
var obj = object.servers[0];
|
|
@@ -278,7 +287,16 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
278
287
|
}
|
|
279
288
|
}
|
|
280
289
|
|
|
281
|
-
if(serverConfig == null)
|
|
290
|
+
if(serverConfig == null) {
|
|
291
|
+
return process.nextTick(function() {
|
|
292
|
+
try {
|
|
293
|
+
callback(new Error("Could not locate any valid servers in initial seed list"));
|
|
294
|
+
} catch (err) {
|
|
295
|
+
if(db) db.close();
|
|
296
|
+
throw err
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
282
300
|
// Ensure no firing off open event before we are ready
|
|
283
301
|
serverConfig.emitOpen = false;
|
|
284
302
|
// Set up all options etc and connect to the database
|
|
@@ -332,7 +350,16 @@ var _finishConnecting = function(serverConfig, object, options, callback) {
|
|
|
332
350
|
var db = new Db(object.dbName, serverConfig, object.db_options);
|
|
333
351
|
// Open the db
|
|
334
352
|
db.open(function(err, db){
|
|
335
|
-
if(err)
|
|
353
|
+
if(err) {
|
|
354
|
+
return process.nextTick(function() {
|
|
355
|
+
try {
|
|
356
|
+
callback(err, null);
|
|
357
|
+
} catch (err) {
|
|
358
|
+
if(db) db.close();
|
|
359
|
+
throw err
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
336
363
|
|
|
337
364
|
if(db.options !== null && !db.options.safe && !db.options.journal
|
|
338
365
|
&& !db.options.w && !db.options.fsync && typeof db.options.w != 'number'
|
|
@@ -355,14 +382,35 @@ var _finishConnecting = function(serverConfig, object, options, callback) {
|
|
|
355
382
|
// Authenticate
|
|
356
383
|
authentication_db.authenticate(object.auth.user, object.auth.password, options, function(err, success){
|
|
357
384
|
if(success){
|
|
358
|
-
|
|
385
|
+
process.nextTick(function() {
|
|
386
|
+
try {
|
|
387
|
+
callback(null, db);
|
|
388
|
+
} catch (err) {
|
|
389
|
+
if(db) db.close();
|
|
390
|
+
throw err
|
|
391
|
+
}
|
|
392
|
+
});
|
|
359
393
|
} else {
|
|
360
394
|
if(db) db.close();
|
|
361
|
-
|
|
395
|
+
process.nextTick(function() {
|
|
396
|
+
try {
|
|
397
|
+
callback(err ? err : new Error('Could not authenticate user ' + auth[0]), null);
|
|
398
|
+
} catch (err) {
|
|
399
|
+
if(db) db.close();
|
|
400
|
+
throw err
|
|
401
|
+
}
|
|
402
|
+
});
|
|
362
403
|
}
|
|
363
404
|
});
|
|
364
405
|
} else {
|
|
365
|
-
|
|
406
|
+
process.nextTick(function() {
|
|
407
|
+
try {
|
|
408
|
+
callback(err, db);
|
|
409
|
+
} catch (err) {
|
|
410
|
+
if(db) db.close();
|
|
411
|
+
throw err
|
|
412
|
+
}
|
|
413
|
+
})
|
|
366
414
|
}
|
|
367
415
|
});
|
|
368
416
|
}
|
|
@@ -42,99 +42,32 @@ MongoReply.prototype.parseHeader = function(binary_reply, bson) {
|
|
|
42
42
|
|
|
43
43
|
MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) {
|
|
44
44
|
raw = raw == null ? false : raw;
|
|
45
|
-
// Just set a doc limit for deserializing
|
|
46
|
-
var docLimitSize = 1024*20;
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
var
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
try {
|
|
47
|
+
// Let's unpack all the bson documents, deserialize them and store them
|
|
48
|
+
for(var object_index = 0; object_index < this.numberReturned; object_index++) {
|
|
49
|
+
var _options = {promoteLongs: bson.promoteLongs};
|
|
50
|
+
|
|
51
|
+
// Read the size of the bson object
|
|
52
|
+
var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
|
53
|
+
|
|
54
|
+
// If we are storing the raw responses to pipe straight through
|
|
55
|
+
if(raw) {
|
|
56
|
+
// Deserialize the object and add to the documents array
|
|
57
|
+
this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize));
|
|
58
|
+
} else {
|
|
59
|
+
// Deserialize the object and add to the documents array
|
|
60
|
+
this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize), _options));
|
|
58
61
|
}
|
|
62
|
+
|
|
63
|
+
// Adjust binary index to point to next block of binary bson data
|
|
64
|
+
this.index = this.index + bsonObjectSize;
|
|
59
65
|
}
|
|
60
|
-
|
|
61
|
-
// Actual main creator of the processFunction setting internal state to control the flow
|
|
62
|
-
var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) {
|
|
63
|
-
var object_index = 0;
|
|
64
|
-
// Internal loop process that will use nextTick to ensure we yield some time
|
|
65
|
-
var processFunction = function() {
|
|
66
|
-
// Adjust batchSize if we have less results left than batchsize
|
|
67
|
-
if((_numberReturned - object_index) < _batchSize) {
|
|
68
|
-
_batchSize = _numberReturned - object_index;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// If raw just process the entries
|
|
72
|
-
if(raw) {
|
|
73
|
-
// Iterate over the batch
|
|
74
|
-
for(var i = 0; i < _batchSize; i++) {
|
|
75
|
-
// Are we done ?
|
|
76
|
-
if(object_index <= _numberReturned) {
|
|
77
|
-
// Read the size of the bson object
|
|
78
|
-
var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24;
|
|
79
|
-
// If we are storing the raw responses to pipe straight through
|
|
80
|
-
_self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize);
|
|
81
|
-
// Adjust binary index to point to next block of binary bson data
|
|
82
|
-
_self.index = _self.index + bsonObjectSize;
|
|
83
|
-
// Update number of docs parsed
|
|
84
|
-
object_index = object_index + 1;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
try {
|
|
89
|
-
// Parse documents
|
|
90
|
-
_self.index = bson.deserializeStream(binary_reply
|
|
91
|
-
, _self.index
|
|
92
|
-
, _batchSize
|
|
93
|
-
, _self.documents
|
|
94
|
-
, object_index
|
|
95
|
-
, {promoteLongs: bson.promoteLongs});
|
|
96
|
-
// Adjust index
|
|
97
|
-
object_index = object_index + _batchSize;
|
|
98
|
-
} catch (err) {
|
|
99
|
-
return callback(err);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// If we have more documents process NextTick
|
|
104
|
-
if(object_index < _numberReturned) {
|
|
105
|
-
processor(processFunction);
|
|
106
|
-
} else {
|
|
107
|
-
callback(null);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Return the process function
|
|
112
|
-
return processFunction;
|
|
113
|
-
}(this, binary_reply, batchSize, this.numberReturned)();
|
|
114
|
-
} else {
|
|
115
|
-
try {
|
|
116
|
-
// Let's unpack all the bson documents, deserialize them and store them
|
|
117
|
-
for(var object_index = 0; object_index < this.numberReturned; object_index++) {
|
|
118
|
-
var _options = {promoteLongs: bson.promoteLongs};
|
|
119
|
-
// Read the size of the bson object
|
|
120
|
-
var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
|
121
|
-
// If we are storing the raw responses to pipe straight through
|
|
122
|
-
if(raw) {
|
|
123
|
-
// Deserialize the object and add to the documents array
|
|
124
|
-
this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize));
|
|
125
|
-
} else {
|
|
126
|
-
// Deserialize the object and add to the documents array
|
|
127
|
-
this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize), _options));
|
|
128
|
-
}
|
|
129
|
-
// Adjust binary index to point to next block of binary bson data
|
|
130
|
-
this.index = this.index + bsonObjectSize;
|
|
131
|
-
}
|
|
132
|
-
} catch(err) {
|
|
133
|
-
return callback(err);
|
|
134
|
-
}
|
|
135
|
-
|
|
66
|
+
|
|
136
67
|
// No error return
|
|
137
68
|
callback(null);
|
|
69
|
+
} catch(err) {
|
|
70
|
+
return callback(err);
|
|
138
71
|
}
|
|
139
72
|
}
|
|
140
73
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{ "name" : "mongodb"
|
|
2
2
|
, "description" : "A node.js driver for MongoDB"
|
|
3
3
|
, "keywords" : ["mongodb", "mongo", "driver", "db"]
|
|
4
|
-
, "version" : "1.3.
|
|
4
|
+
, "version" : "1.3.19"
|
|
5
5
|
, "author" : "Christian Amor Kvalheim <christkv@gmail.com>"
|
|
6
6
|
, "contributors" : [ "Aaron Heckmann",
|
|
7
7
|
"Christoph Pojer",
|
package/t.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
var mongodb = require('./lib/mongodb');
|
|
2
|
+
|
|
3
|
+
var mongoserver = new mongodb.Server('localhost', 27017, {});
|
|
4
|
+
var db_conn = new mongodb.Db('test1', mongoserver, { w : 1 });
|
|
5
|
+
|
|
6
|
+
db_conn.on('open', function () {
|
|
7
|
+
console.log("this is an open event");
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
db_conn.on('close', function () {
|
|
11
|
+
console.log("this is a close event");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
db_conn.on('reconnect', function () {
|
|
15
|
+
console.log("this is a reconnect event");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
db_conn.open(function (err) {
|
|
19
|
+
if (err) throw err;
|
|
20
|
+
|
|
21
|
+
var col = db_conn.collection('test');
|
|
22
|
+
|
|
23
|
+
var count = 0;
|
|
24
|
+
// Run a simple 'find' query every second
|
|
25
|
+
setInterval(function() {
|
|
26
|
+
col.findOne(function(err, item) {
|
|
27
|
+
if (err) {
|
|
28
|
+
return console.log("mongodb query not ok %d", count)
|
|
29
|
+
}
|
|
30
|
+
console.log("mongodb query ok %d", count);
|
|
31
|
+
count++;
|
|
32
|
+
})
|
|
33
|
+
if (count == 40) {
|
|
34
|
+
db_conn.close();
|
|
35
|
+
}
|
|
36
|
+
}, 1000)
|
|
37
|
+
console.log('hi');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// var MongoClient = require('./lib/mongodb').MongoClient
|
|
41
|
+
// , Server = require('./lib/mongodb').Server
|
|
42
|
+
// , ReplSet = require('./lib/mongodb').ReplSet
|
|
43
|
+
// , Db = require('./lib/mongodb').Db;
|
|
44
|
+
// var format = require('util').format;
|
|
45
|
+
|
|
46
|
+
// var host = process.env['MONGO_NODE_DRIVER_HOST'] || 'localhost';
|
|
47
|
+
// var port = process.env['MONGO_NODE_DRIVER_PORT'] || 27017;
|
|
48
|
+
// var url = format("mongodb://%s:%s,%s:%s,%s:%s/node-mongo-examples"
|
|
49
|
+
// , host, port, host, 27018, host, 27019);
|
|
50
|
+
// var url = "mongodb://localhost:27017/node-mongo-examples"
|
|
51
|
+
// // console.dir(url)
|
|
52
|
+
|
|
53
|
+
// // MongoClient.connect(url, function(err, db) {
|
|
54
|
+
// // new Db("node-mongo-examples", new Server("localhost", 27017), {w:1}).open(function(err, db) {
|
|
55
|
+
// var replSet = new ReplSet([new Server("localhost", 31000)
|
|
56
|
+
// , new Server("localhost", 31001)
|
|
57
|
+
// , new Server("localhost", 31002)])
|
|
58
|
+
// new Db("node-mongo-examples", replSet, {safe:true}).open(function(err, db) {
|
|
59
|
+
// if(err) throw err;
|
|
60
|
+
// console.log("=========================== 0")
|
|
61
|
+
// db.close();
|
|
62
|
+
// });
|
|
63
|
+
|
|
64
|
+
// // console.log("------------------------- 0")
|
|
65
|
+
|
|
66
|
+
// // db.on('error', function(err, db) {
|
|
67
|
+
// // console.log("---------------------- GOT ERROR")
|
|
68
|
+
// // console.dir(err)
|
|
69
|
+
// // db.close(function() {
|
|
70
|
+
// // console.log("----------------- error")
|
|
71
|
+
// // process.exit(1);
|
|
72
|
+
// // })
|
|
73
|
+
// // });
|
|
74
|
+
// // // throw new Error("3")
|
|
75
|
+
|
|
76
|
+
// // console.log('connected');
|
|
77
|
+
|
|
78
|
+
// // db.collection('t').findOne(function(err, result) {
|
|
79
|
+
// // console.log("33333")
|
|
80
|
+
// // throw new Error("3")
|
|
81
|
+
// // })
|
|
82
|
+
|
|
83
|
+
// // thisMethodDoesNotExists('foo', 'bar', 123);
|
|
84
|
+
|
|
85
|
+
// process.on("uncaughtException", function(err) {
|
|
86
|
+
// console.log("######################")
|
|
87
|
+
// })
|
|
88
|
+
|
|
89
|
+
// // var now;
|
|
90
|
+
// // var obj, i;
|
|
91
|
+
// // var count = 10000000;
|
|
92
|
+
// // var key = 'key';
|
|
93
|
+
|
|
94
|
+
// // obj = {};
|
|
95
|
+
// // now = Date.now();
|
|
96
|
+
// // for (i = 0; i < count; i++) {
|
|
97
|
+
// // obj[key] = 1;
|
|
98
|
+
// // obj[key] = null;
|
|
99
|
+
// // }
|
|
100
|
+
// // console.log('null assignment(`obj[key] = null`):\n %d ms', Date.now() - now);
|
|
101
|
+
|
|
102
|
+
// // obj = {};
|
|
103
|
+
// // now = Date.now();
|
|
104
|
+
// // for (i = 0; i < count; i++) {
|
|
105
|
+
// // obj[key] = 1;
|
|
106
|
+
// // delete obj[key];
|
|
107
|
+
// // }
|
|
108
|
+
// // console.log('deleting property(`delete obj[key]`):\n %d ms', Date.now() - now);
|
|
109
|
+
|
|
110
|
+
// // // var mongodb = require('./lib/mongodb');
|
|
111
|
+
|
|
112
|
+
// // // // var url = 'mongodb://user:pass@host1,host2,host3/db';
|
|
113
|
+
// // // var url = 'mongodb://127.0.0.1:31000,192.168.2.173:31001,127.0.0.1:31002/test';
|
|
114
|
+
// // // var options = {db: {safe: true}, server: {auto_reconnect: true}};
|
|
115
|
+
|
|
116
|
+
// // // mongodb.connect(url, options, function (err, db) {
|
|
117
|
+
// // // if (err) {
|
|
118
|
+
// // // console.log(err);
|
|
119
|
+
// // // process.exit(1);
|
|
120
|
+
// // // }
|
|
121
|
+
|
|
122
|
+
// // // db.collection('test', function (err, c) {
|
|
123
|
+
// // // if (err) {
|
|
124
|
+
// // // console.log(err);
|
|
125
|
+
// // // process.exit(2);
|
|
126
|
+
// // // }
|
|
127
|
+
|
|
128
|
+
// // // var successCount = 0;
|
|
129
|
+
// // // var errCount = 0;
|
|
130
|
+
// // // var lastErr = null;
|
|
131
|
+
// // // setInterval(function () {
|
|
132
|
+
// // // c.find({}).limit(100).toArray(function (err, results) {
|
|
133
|
+
// // // if (err) {
|
|
134
|
+
// // // lastErr = err;
|
|
135
|
+
// // // errCount++;
|
|
136
|
+
// // // } else {
|
|
137
|
+
// // // successCount++;
|
|
138
|
+
// // // }
|
|
139
|
+
// // // });
|
|
140
|
+
// // // }, 100);
|
|
141
|
+
|
|
142
|
+
// // // setInterval(function () {
|
|
143
|
+
// // // console.log("STATUS", successCount, errCount);
|
|
144
|
+
// // // }, 1000);
|
|
145
|
+
|
|
146
|
+
// // // });
|
|
147
|
+
// // // });
|
package/install.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
var spawn = require('child_process').spawn,
|
|
2
|
-
exec = require('child_process').exec;
|
|
3
|
-
|
|
4
|
-
process.stdout.write("================================================================================\n");
|
|
5
|
-
process.stdout.write("= =\n");
|
|
6
|
-
process.stdout.write("= To install with C++ bson parser do <npm install mongodb --mongodb:native> =\n");
|
|
7
|
-
process.stdout.write("= =\n");
|
|
8
|
-
process.stdout.write("================================================================================\n");
|
|
9
|
-
|
|
10
|
-
// Check if we want to build the native code
|
|
11
|
-
var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false';
|
|
12
|
-
build_native = build_native == 'true' ? true : false;
|
|
13
|
-
// If we are building the native bson extension ensure we use gmake if available
|
|
14
|
-
if(build_native) {
|
|
15
|
-
// Check if we need to use gmake
|
|
16
|
-
exec('which gmake', function(err, stdout, stderr) {
|
|
17
|
-
// Set up spawn command
|
|
18
|
-
var make = null;
|
|
19
|
-
// No gmake build using make
|
|
20
|
-
if(err != null) {
|
|
21
|
-
make = spawn('make', ['total']);
|
|
22
|
-
} else {
|
|
23
|
-
make = spawn('gmake', ['total']);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Execute spawn
|
|
27
|
-
make.stdout.on('data', function(data) {
|
|
28
|
-
process.stdout.write(data);
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
make.stderr.on('data', function(data) {
|
|
32
|
-
process.stdout.write(data);
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
make.on('exit', function(code) {
|
|
36
|
-
process.stdout.write('child process exited with code ' + code + "\n");
|
|
37
|
-
})
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|