PageRenderTime 78ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/server/node_modules/mongoose/node_modules/mongodb/lib/server.js

https://gitlab.com/angtrim/gaia-back-due
JavaScript | 437 lines | 227 code | 71 blank | 139 comment | 40 complexity | 5add7f5388c30009cf6e535f788d451b MD5 | raw file
  1. "use strict";
  2. var EventEmitter = require('events').EventEmitter
  3. , inherits = require('util').inherits
  4. , CServer = require('mongodb-core').Server
  5. , Cursor = require('./cursor')
  6. , AggregationCursor = require('./aggregation_cursor')
  7. , CommandCursor = require('./command_cursor')
  8. , f = require('util').format
  9. , ServerCapabilities = require('./topology_base').ServerCapabilities
  10. , Store = require('./topology_base').Store
  11. , Define = require('./metadata')
  12. , MongoError = require('mongodb-core').MongoError
  13. , shallowClone = require('./utils').shallowClone;
  14. /**
  15. * @fileOverview The **Server** class is a class that represents a single server topology and is
  16. * used to construct connections.
  17. *
  18. * **Server Should not be used, use MongoClient.connect**
  19. * @example
  20. * var Db = require('mongodb').Db,
  21. * Server = require('mongodb').Server,
  22. * test = require('assert');
  23. * // Connect using single Server
  24. * var db = new Db('test', new Server('localhost', 27017););
  25. * db.open(function(err, db) {
  26. * // Get an additional db
  27. * db.close();
  28. * });
  29. */
  30. /**
  31. * Creates a new Server instance
  32. * @class
  33. * @deprecated
  34. * @param {string} host The host for the server, can be either an IP4, IP6 or domain socket style host.
  35. * @param {number} [port] The server port if IP4.
  36. * @param {object} [options=null] Optional settings.
  37. * @param {number} [options.poolSize=5] Number of connections in the connection pool for each server instance, set to 5 as default for legacy reasons.
  38. * @param {boolean} [options.ssl=false] Use ssl connection (needs to have a mongod server with ssl support)
  39. * @param {object} [options.sslValidate=true] Validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher)
  40. * @param {array} [options.sslCA=null] Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher)
  41. * @param {(Buffer|string)} [options.sslCert=null] String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
  42. * @param {(Buffer|string)} [options.sslKey=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)
  43. * @param {(Buffer|string)} [options.sslPass=null] String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher)
  44. * @param {object} [options.socketOptions=null] Socket options
  45. * @param {boolean} [options.socketOptions.autoReconnect=false] Reconnect on error.
  46. * @param {boolean} [options.socketOptions.noDelay=true] TCP Socket NoDelay option.
  47. * @param {number} [options.socketOptions.keepAlive=0] TCP KeepAlive on the socket with a X ms delay before start.
  48. * @param {number} [options.socketOptions.connectTimeoutMS=0] TCP Connection timeout setting
  49. * @param {number} [options.socketOptions.socketTimeoutMS=0] TCP Socket timeout setting
  50. * @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
  51. * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
  52. * @fires Server#connect
  53. * @fires Server#close
  54. * @fires Server#error
  55. * @fires Server#timeout
  56. * @fires Server#parseError
  57. * @fires Server#reconnect
  58. * @return {Server} a Server instance.
  59. */
  60. var Server = function(host, port, options) {
  61. options = options || {};
  62. if(!(this instanceof Server)) return new Server(host, port, options);
  63. EventEmitter.call(this);
  64. var self = this;
  65. // Store option defaults
  66. var storeOptions = {
  67. force: false
  68. , bufferMaxEntries: -1
  69. }
  70. // Shared global store
  71. var store = options.store || new Store(self, storeOptions);
  72. // Detect if we have a socket connection
  73. if(host.indexOf('\/') != -1) {
  74. if(port != null && typeof port == 'object') {
  75. options = port;
  76. port = null;
  77. }
  78. } else if(port == null) {
  79. throw MongoError.create({message: 'port must be specified', driver:true});
  80. }
  81. // Clone options
  82. var clonedOptions = shallowClone(options);
  83. clonedOptions.host = host;
  84. clonedOptions.port = port;
  85. // Reconnect
  86. var reconnect = typeof options.auto_reconnect == 'boolean' ? options.auto_reconnect : true;
  87. reconnect = typeof options.autoReconnect == 'boolean' ? options.autoReconnect : reconnect;
  88. var emitError = typeof options.emitError == 'boolean' ? options.emitError : true;
  89. var poolSize = typeof options.poolSize == 'number' ? options.poolSize : 5;
  90. // Socket options passed down
  91. if(options.socketOptions) {
  92. if(options.socketOptions.connectTimeoutMS) {
  93. this.connectTimeoutMS = options.socketOptions.connectTimeoutMS;
  94. clonedOptions.connectionTimeout = options.socketOptions.connectTimeoutMS;
  95. }
  96. if(options.socketOptions.socketTimeoutMS) {
  97. clonedOptions.socketTimeout = options.socketOptions.socketTimeoutMS;
  98. }
  99. if(typeof options.socketOptions.keepAlive == 'number') {
  100. clonedOptions.keepAliveInitialDelay = options.socketOptions.keepAlive;
  101. clonedOptions.keepAlive = true;
  102. }
  103. if(typeof options.socketOptions.noDelay == 'boolean') {
  104. clonedOptions.noDelay = options.socketOptions.noDelay;
  105. }
  106. }
  107. // Add the cursor factory function
  108. clonedOptions.cursorFactory = Cursor;
  109. clonedOptions.reconnect = reconnect;
  110. clonedOptions.emitError = emitError;
  111. clonedOptions.size = poolSize;
  112. // Translate the options
  113. if(clonedOptions.sslCA) clonedOptions.ca = clonedOptions.sslCA;
  114. if(typeof clonedOptions.sslValidate == 'boolean') clonedOptions.rejectUnauthorized = clonedOptions.sslValidate;
  115. if(clonedOptions.sslKey) clonedOptions.key = clonedOptions.sslKey;
  116. if(clonedOptions.sslCert) clonedOptions.cert = clonedOptions.sslCert;
  117. if(clonedOptions.sslPass) clonedOptions.passphrase = clonedOptions.sslPass;
  118. // Add the non connection store
  119. clonedOptions.disconnectHandler = store;
  120. // Create an instance of a server instance from mongodb-core
  121. var server = new CServer(clonedOptions);
  122. // Server capabilities
  123. var sCapabilities = null;
  124. // Define the internal properties
  125. this.s = {
  126. // Create an instance of a server instance from mongodb-core
  127. server: server
  128. // Server capabilities
  129. , sCapabilities: null
  130. // Cloned options
  131. , clonedOptions: clonedOptions
  132. // Reconnect
  133. , reconnect: reconnect
  134. // Emit error
  135. , emitError: emitError
  136. // Pool size
  137. , poolSize: poolSize
  138. // Store Options
  139. , storeOptions: storeOptions
  140. // Store
  141. , store: store
  142. // Host
  143. , host: host
  144. // Port
  145. , port: port
  146. // Options
  147. , options: options
  148. }
  149. // BSON property
  150. Object.defineProperty(this, 'bson', {
  151. enumerable: true, get: function() {
  152. return self.s.server.bson;
  153. }
  154. });
  155. // Last ismaster
  156. Object.defineProperty(this, 'isMasterDoc', {
  157. enumerable:true, get: function() {
  158. return self.s.server.lastIsMaster();
  159. }
  160. });
  161. // Last ismaster
  162. Object.defineProperty(this, 'poolSize', {
  163. enumerable:true, get: function() { return self.s.server.connections().length; }
  164. });
  165. Object.defineProperty(this, 'autoReconnect', {
  166. enumerable:true, get: function() { return self.s.reconnect; }
  167. });
  168. Object.defineProperty(this, 'host', {
  169. enumerable:true, get: function() { return self.s.host; }
  170. });
  171. Object.defineProperty(this, 'port', {
  172. enumerable:true, get: function() { return self.s.port; }
  173. });
  174. }
  175. inherits(Server, EventEmitter);
  176. var define = Server.define = new Define('Server', Server, false);
  177. Server.prototype.parserType = function() {
  178. return this.s.server.parserType();
  179. }
  180. define.classMethod('parserType', {callback: false, promise:false, returns: [String]});
  181. // Connect
  182. Server.prototype.connect = function(db, _options, callback) {
  183. var self = this;
  184. if('function' === typeof _options) callback = _options, _options = {};
  185. if(_options == null) _options = {};
  186. if(!('function' === typeof callback)) callback = null;
  187. self.s.options = _options;
  188. // Update bufferMaxEntries
  189. self.s.storeOptions.bufferMaxEntries = db.bufferMaxEntries;
  190. // Error handler
  191. var connectErrorHandler = function(event) {
  192. return function(err) {
  193. // Remove all event handlers
  194. var events = ['timeout', 'error', 'close'];
  195. events.forEach(function(e) {
  196. self.s.server.removeListener(e, connectHandlers[e]);
  197. });
  198. self.s.server.removeListener('connect', connectErrorHandler);
  199. // Try to callback
  200. try {
  201. callback(err);
  202. } catch(err) {
  203. process.nextTick(function() { throw err; })
  204. }
  205. }
  206. }
  207. // Actual handler
  208. var errorHandler = function(event) {
  209. return function(err) {
  210. if(event != 'error') {
  211. self.emit(event, err);
  212. }
  213. }
  214. }
  215. // Error handler
  216. var reconnectHandler = function(err) {
  217. self.emit('reconnect', self);
  218. self.s.store.execute();
  219. }
  220. // Destroy called on topology, perform cleanup
  221. var destroyHandler = function() {
  222. self.s.store.flush();
  223. }
  224. // Connect handler
  225. var connectHandler = function() {
  226. // Clear out all the current handlers left over
  227. ["timeout", "error", "close"].forEach(function(e) {
  228. self.s.server.removeAllListeners(e);
  229. });
  230. // Set up listeners
  231. self.s.server.once('timeout', errorHandler('timeout'));
  232. self.s.server.once('error', errorHandler('error'));
  233. self.s.server.on('close', errorHandler('close'));
  234. // Only called on destroy
  235. self.s.server.once('destroy', destroyHandler);
  236. // Emit open event
  237. self.emit('open', null, self);
  238. // Return correctly
  239. try {
  240. callback(null, self);
  241. } catch(err) {
  242. console.log(err.stack)
  243. process.nextTick(function() { throw err; })
  244. }
  245. }
  246. // Set up listeners
  247. var connectHandlers = {
  248. timeout: connectErrorHandler('timeout'),
  249. error: connectErrorHandler('error'),
  250. close: connectErrorHandler('close')
  251. };
  252. // Add the event handlers
  253. self.s.server.once('timeout', connectHandlers.timeout);
  254. self.s.server.once('error', connectHandlers.error);
  255. self.s.server.once('close', connectHandlers.close);
  256. self.s.server.once('connect', connectHandler);
  257. // Reconnect server
  258. self.s.server.on('reconnect', reconnectHandler);
  259. // Start connection
  260. self.s.server.connect(_options);
  261. }
  262. // Server capabilities
  263. Server.prototype.capabilities = function() {
  264. if(this.s.sCapabilities) return this.s.sCapabilities;
  265. if(this.s.server.lastIsMaster() == null) return null;
  266. this.s.sCapabilities = new ServerCapabilities(this.s.server.lastIsMaster());
  267. return this.s.sCapabilities;
  268. }
  269. define.classMethod('capabilities', {callback: false, promise:false, returns: [ServerCapabilities]});
  270. // Command
  271. Server.prototype.command = function(ns, cmd, options, callback) {
  272. this.s.server.command(ns, cmd, options, callback);
  273. }
  274. define.classMethod('command', {callback: true, promise:false});
  275. // Insert
  276. Server.prototype.insert = function(ns, ops, options, callback) {
  277. this.s.server.insert(ns, ops, options, callback);
  278. }
  279. define.classMethod('insert', {callback: true, promise:false});
  280. // Update
  281. Server.prototype.update = function(ns, ops, options, callback) {
  282. this.s.server.update(ns, ops, options, callback);
  283. }
  284. define.classMethod('update', {callback: true, promise:false});
  285. // Remove
  286. Server.prototype.remove = function(ns, ops, options, callback) {
  287. this.s.server.remove(ns, ops, options, callback);
  288. }
  289. define.classMethod('remove', {callback: true, promise:false});
  290. // IsConnected
  291. Server.prototype.isConnected = function() {
  292. return this.s.server.isConnected();
  293. }
  294. define.classMethod('isConnected', {callback: false, promise:false, returns: [Boolean]});
  295. // Insert
  296. Server.prototype.cursor = function(ns, cmd, options) {
  297. options.disconnectHandler = this.s.store;
  298. return this.s.server.cursor(ns, cmd, options);
  299. }
  300. define.classMethod('cursor', {callback: false, promise:false, returns: [Cursor, AggregationCursor, CommandCursor]});
  301. Server.prototype.setBSONParserType = function(type) {
  302. return this.s.server.setBSONParserType(type);
  303. }
  304. Server.prototype.lastIsMaster = function() {
  305. return this.s.server.lastIsMaster();
  306. }
  307. Server.prototype.close = function(forceClosed) {
  308. this.s.server.destroy();
  309. // We need to wash out all stored processes
  310. if(forceClosed == true) {
  311. this.s.storeOptions.force = forceClosed;
  312. this.s.store.flush();
  313. }
  314. }
  315. define.classMethod('close', {callback: false, promise:false});
  316. Server.prototype.auth = function() {
  317. var args = Array.prototype.slice.call(arguments, 0);
  318. this.s.server.auth.apply(this.s.server, args);
  319. }
  320. define.classMethod('auth', {callback: true, promise:false});
  321. /**
  322. * All raw connections
  323. * @method
  324. * @return {array}
  325. */
  326. Server.prototype.connections = function() {
  327. return this.s.server.connections();
  328. }
  329. define.classMethod('connections', {callback: false, promise:false, returns:[Array]});
  330. /**
  331. * Server connect event
  332. *
  333. * @event Server#connect
  334. * @type {object}
  335. */
  336. /**
  337. * Server close event
  338. *
  339. * @event Server#close
  340. * @type {object}
  341. */
  342. /**
  343. * Server reconnect event
  344. *
  345. * @event Server#reconnect
  346. * @type {object}
  347. */
  348. /**
  349. * Server error event
  350. *
  351. * @event Server#error
  352. * @type {MongoError}
  353. */
  354. /**
  355. * Server timeout event
  356. *
  357. * @event Server#timeout
  358. * @type {object}
  359. */
  360. /**
  361. * Server parseError event
  362. *
  363. * @event Server#parseError
  364. * @type {object}
  365. */
  366. module.exports = Server;