| 
									
										
										
										
											2013-12-02 16:19:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-01 16:59:04 -05:00
										 |  |  | 'use strict'; | 
					
						
							| 
									
										
										
										
											2013-12-02 16:19:30 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | (function(module) { | 
					
						
							| 
									
										
										
										
											2014-03-01 16:59:04 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:04 -05:00
										 |  |  | 	var winston = require('winston'), | 
					
						
							| 
									
										
										
										
											2013-12-04 15:11:17 -05:00
										 |  |  | 		async = require('async'), | 
					
						
							| 
									
										
										
										
											2013-12-02 16:19:30 -05:00
										 |  |  | 		nconf = require('nconf'), | 
					
						
							| 
									
										
										
										
											2014-07-02 14:07:08 -04:00
										 |  |  | 		session = require('express-session'), | 
					
						
							| 
									
										
										
										
											2015-05-19 14:55:06 -04:00
										 |  |  | 		_ = require('underscore'), | 
					
						
							| 
									
										
										
										
											2015-06-05 13:33:58 -04:00
										 |  |  | 		semver = require('semver'), | 
					
						
							| 
									
										
										
										
											2014-09-29 12:13:10 -04:00
										 |  |  | 		db, mongoClient; | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:04 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 14:55:06 -04:00
										 |  |  | 	_.mixin(require('underscore.deep')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 	module.questions = [ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: 'mongo:host', | 
					
						
							|  |  |  | 			description: 'Host IP or address of your MongoDB instance', | 
					
						
							|  |  |  | 			'default': nconf.get('mongo:host') || '127.0.0.1' | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: 'mongo:port', | 
					
						
							|  |  |  | 			description: 'Host port of your MongoDB instance', | 
					
						
							|  |  |  | 			'default': nconf.get('mongo:port') || 27017 | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: 'mongo:username', | 
					
						
							| 
									
										
										
										
											2015-02-25 22:27:19 +01:00
										 |  |  | 			description: 'MongoDB username', | 
					
						
							|  |  |  | 			'default': nconf.get('mongo:username') || '' | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: 'mongo:password', | 
					
						
							| 
									
										
										
										
											2014-04-14 20:33:02 -04:00
										 |  |  | 			description: 'Password of your MongoDB database', | 
					
						
							| 
									
										
										
										
											2015-02-25 22:27:19 +01:00
										 |  |  | 			hidden: true, | 
					
						
							|  |  |  | 			before: function(value) { value = value || nconf.get('mongo:password') || ''; return value; } | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "mongo:database", | 
					
						
							|  |  |  | 			description: "Which database to use", | 
					
						
							|  |  |  | 			'default': nconf.get('mongo:database') || 0 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	]; | 
					
						
							| 
									
										
										
										
											2013-12-02 16:19:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-03 19:38:48 -04:00
										 |  |  | 	module.helpers = module.helpers || {}; | 
					
						
							|  |  |  | 	module.helpers.mongo = require('./mongo/helpers'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 14:21:08 -05:00
										 |  |  | 	module.init = function(callback) { | 
					
						
							| 
									
										
										
										
											2015-04-01 12:28:01 -04:00
										 |  |  | 		callback = callback || function() {}; | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 		try { | 
					
						
							| 
									
										
										
										
											2014-09-23 17:18:20 -04:00
										 |  |  | 			var sessionStore; | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 			mongoClient = require('mongodb').MongoClient; | 
					
						
							| 
									
										
										
										
											2014-09-23 17:18:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (!nconf.get('redis')) { | 
					
						
							| 
									
										
										
										
											2015-03-03 15:12:40 -05:00
										 |  |  | 				sessionStore = require('connect-mongo')(session); | 
					
						
							| 
									
										
										
										
											2014-09-23 17:18:20 -04:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				sessionStore = require('connect-redis')(session); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 		} catch (err) { | 
					
						
							|  |  |  | 			winston.error('Unable to initialize MongoDB! Is MongoDB installed? Error :' + err.message); | 
					
						
							| 
									
										
										
										
											2014-10-30 22:19:11 -04:00
										 |  |  | 			return callback(err); | 
					
						
							| 
									
										
										
										
											2014-04-14 13:41:33 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-10-03 16:31:53 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var usernamePassword = ''; | 
					
						
							|  |  |  | 		if (nconf.get('mongo:username') && nconf.get('mongo:password')) { | 
					
						
							| 
									
										
										
										
											2015-07-17 19:03:25 -04:00
										 |  |  | 			usernamePassword = nconf.get('mongo:username') + ':' + encodeURIComponent(nconf.get('mongo:password')) + '@'; | 
					
						
							| 
									
										
										
										
											2014-10-03 16:31:53 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 11:08:02 -04:00
										 |  |  | 		// Sensible defaults for Mongo, if not set
 | 
					
						
							|  |  |  | 		if (!nconf.get('mongo:host')) { | 
					
						
							|  |  |  | 			nconf.set('mongo:host', '127.0.0.1'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!nconf.get('mongo:port')) { | 
					
						
							|  |  |  | 			nconf.set('mongo:port', 27017); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!nconf.get('mongo:database')) { | 
					
						
							|  |  |  | 			nconf.set('mongo:database', '0'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-25 08:05:33 -07:00
										 |  |  | 		var hosts = nconf.get('mongo:host').split(','); | 
					
						
							| 
									
										
										
										
											2015-04-25 08:16:27 -07:00
										 |  |  | 		var ports = nconf.get('mongo:port').toString().split(','); | 
					
						
							| 
									
										
										
										
											2015-04-25 08:05:33 -07:00
										 |  |  | 		var servers = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-27 11:08:58 -07:00
										 |  |  | 		for (var i = 0; i < hosts.length; i++) { | 
					
						
							|  |  |  | 			servers.push(hosts[i] + ':' + ports[i]); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-04-25 08:05:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var connString = 'mongodb://' + usernamePassword + servers.join() + '/' + nconf.get('mongo:database'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 01:20:42 -04:00
										 |  |  | 		var connOptions = { | 
					
						
							|  |  |  | 			server: { | 
					
						
							| 
									
										
										
										
											2014-12-14 22:34:53 -05:00
										 |  |  | 				poolSize: parseInt(nconf.get('mongo:poolSize'), 10) || 10 | 
					
						
							| 
									
										
										
										
											2014-09-27 01:20:42 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2015-05-19 14:55:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 01:20:42 -04:00
										 |  |  | 		mongoClient.connect(connString, connOptions, function(err, _db) { | 
					
						
							| 
									
										
										
										
											2014-10-30 22:19:11 -04:00
										 |  |  | 			if (err) { | 
					
						
							| 
									
										
										
										
											2013-12-03 14:21:08 -05:00
										 |  |  | 				winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message); | 
					
						
							| 
									
										
										
										
											2014-10-30 22:19:11 -04:00
										 |  |  | 				return callback(err); | 
					
						
							| 
									
										
										
										
											2013-12-03 14:21:08 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-12-03 13:36:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 14:34:25 -05:00
										 |  |  | 			db = _db; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 14:22:31 -05:00
										 |  |  | 			module.client = db; | 
					
						
							| 
									
										
										
										
											2015-04-01 12:28:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-23 17:18:20 -04:00
										 |  |  | 			if (!nconf.get('redis')) { | 
					
						
							|  |  |  | 				module.sessionStore = new sessionStore({ | 
					
						
							|  |  |  | 					db: db | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				module.sessionStore = new sessionStore({ | 
					
						
							|  |  |  | 					client: require('./redis').connect(), | 
					
						
							|  |  |  | 					ttl: 60 * 60 * 24 * 14 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-12-03 13:36:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-11 15:44:53 -04:00
										 |  |  | 			require('./mongo/main')(db, module); | 
					
						
							|  |  |  | 			require('./mongo/hash')(db, module); | 
					
						
							|  |  |  | 			require('./mongo/sets')(db, module); | 
					
						
							|  |  |  | 			require('./mongo/sorted')(db, module); | 
					
						
							|  |  |  | 			require('./mongo/list')(db, module); | 
					
						
							| 
									
										
										
										
											2013-12-03 13:36:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 10:57:13 +02:00
										 |  |  | 			if (nconf.get('mongo:password') && nconf.get('mongo:username')) { | 
					
						
							| 
									
										
										
										
											2013-12-06 14:31:11 -05:00
										 |  |  | 				db.authenticate(nconf.get('mongo:username'), nconf.get('mongo:password'), function (err) { | 
					
						
							| 
									
										
										
										
											2014-09-21 22:07:08 -04:00
										 |  |  | 					if (err) { | 
					
						
							|  |  |  | 						winston.error(err.stack); | 
					
						
							| 
									
										
										
										
											2013-12-06 14:34:25 -05:00
										 |  |  | 						process.exit(); | 
					
						
							| 
									
										
										
										
											2013-12-06 14:31:11 -05:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-01-05 19:08:36 -05:00
										 |  |  | 					createIndices(); | 
					
						
							| 
									
										
										
										
											2013-12-05 21:07:35 -05:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2013-12-06 14:34:25 -05:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2014-02-08 14:05:45 -05:00
										 |  |  | 				winston.warn('You have no mongo password setup!'); | 
					
						
							| 
									
										
										
										
											2014-01-05 19:08:36 -05:00
										 |  |  | 				createIndices(); | 
					
						
							| 
									
										
										
										
											2013-12-06 14:31:11 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-12-05 21:07:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-05 19:08:36 -05:00
										 |  |  | 			function createIndices() { | 
					
						
							| 
									
										
										
										
											2015-12-11 10:57:13 +02:00
										 |  |  | 				winston.info('[database] Checking database indices.'); | 
					
						
							| 
									
										
										
										
											2015-04-01 12:28:01 -04:00
										 |  |  | 				async.parallel([ | 
					
						
							|  |  |  | 					async.apply(createIndex, 'objects', {_key: 1, score: -1}, {background: true}), | 
					
						
							| 
									
										
										
										
											2015-05-11 18:07:45 -04:00
										 |  |  | 					async.apply(createIndex, 'objects', {_key: 1, value: -1}, {background: true, unique: true, sparse: true}), | 
					
						
							| 
									
										
										
										
											2015-12-11 10:57:13 +02:00
										 |  |  | 					async.apply(createIndex, 'objects', {expireAt: 1}, {expireAfterSeconds: 0, background: true}) | 
					
						
							| 
									
										
										
										
											2015-04-27 22:51:44 -04:00
										 |  |  | 				], function(err) { | 
					
						
							| 
									
										
										
										
											2014-10-15 15:11:01 -04:00
										 |  |  | 					if (err) { | 
					
						
							| 
									
										
										
										
											2014-09-03 23:43:07 -04:00
										 |  |  | 						winston.error('Error creating index ' + err.message); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-04-01 12:28:01 -04:00
										 |  |  | 					callback(err); | 
					
						
							| 
									
										
										
										
											2014-09-03 23:43:07 -04:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2013-12-06 14:34:25 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-12-11 10:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			function createIndex(collection, index, options, callback) { | 
					
						
							|  |  |  | 				db.collection(collection).ensureIndex(index, options, callback); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-12-03 14:21:08 -05:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-01 16:59:04 -05:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2013-12-02 22:48:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-05 13:33:58 -04:00
										 |  |  | 	module.checkCompatibility = function(callback) { | 
					
						
							|  |  |  | 		var mongoPkg = require.main.require('./node_modules/mongodb/package.json'), | 
					
						
							|  |  |  | 			err = semver.lt(mongoPkg.version, '2.0.0') ? new Error('The `mongodb` package is out-of-date, please run `./nodebb setup` again.') : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (err) { | 
					
						
							|  |  |  | 			err.stacktrace = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		callback(err); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-08 15:36:06 -04:00
										 |  |  | 	module.info = function(db, callback) { | 
					
						
							| 
									
										
										
										
											2015-08-12 16:14:48 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			serverStatus: function(next) { | 
					
						
							| 
									
										
										
										
											2015-08-12 16:14:48 -04:00
										 |  |  | 				db.command({'serverStatus': 1}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			stats: function(next) { | 
					
						
							| 
									
										
										
										
											2015-10-17 18:37:07 -04:00
										 |  |  | 				db.command({'dbStats': 1}, next); | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			listCollections: function(next) { | 
					
						
							|  |  |  | 				db.listCollections().toArray(function(err, items) { | 
					
						
							|  |  |  | 					if (err) { | 
					
						
							|  |  |  | 						return next(err); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					async.map(items, function(collection, next) { | 
					
						
							|  |  |  | 						db.collection(collection.name).stats(next); | 
					
						
							|  |  |  | 					}, next); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2015-08-12 16:14:48 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}, function(err, results) { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							| 
									
										
										
										
											2015-05-08 15:36:06 -04:00
										 |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-08-12 16:14:48 -04:00
										 |  |  | 			var stats = results.stats; | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			var scale = 1024 * 1024; | 
					
						
							| 
									
										
										
										
											2015-05-08 15:36:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 18:34:04 -04:00
										 |  |  | 			results.listCollections = results.listCollections.map(function(collectionInfo) { | 
					
						
							|  |  |  | 				return { | 
					
						
							|  |  |  | 					name: collectionInfo.ns, | 
					
						
							|  |  |  | 					count: collectionInfo.count, | 
					
						
							|  |  |  | 					size: collectionInfo.size, | 
					
						
							|  |  |  | 					avgObjSize: collectionInfo.avgObjSize, | 
					
						
							|  |  |  | 					storageSize: collectionInfo.storageSize, | 
					
						
							|  |  |  | 					totalIndexSize: collectionInfo.totalIndexSize, | 
					
						
							|  |  |  | 					indexSizes: collectionInfo.indexSizes | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			stats.mem = results.serverStatus.mem; | 
					
						
							|  |  |  | 			stats.collectionData = results.listCollections; | 
					
						
							|  |  |  | 			stats.network = results.serverStatus.network; | 
					
						
							| 
									
										
										
										
											2015-05-08 15:36:06 -04:00
										 |  |  | 			stats.raw = JSON.stringify(stats, null, 4); | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-26 08:40:08 +02:00
										 |  |  | 			stats.avgObjSize = stats.avgObjSize.toFixed(2); | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			stats.dataSize = (stats.dataSize / scale).toFixed(2); | 
					
						
							|  |  |  | 			stats.storageSize = (stats.storageSize / scale).toFixed(2); | 
					
						
							| 
									
										
										
										
											2015-10-17 18:38:34 -04:00
										 |  |  | 			stats.fileSize = stats.fileSize ? (stats.fileSize / scale).toFixed(2) : 0; | 
					
						
							| 
									
										
										
										
											2015-10-17 18:26:03 -04:00
										 |  |  | 			stats.indexSize = (stats.indexSize / scale).toFixed(2); | 
					
						
							|  |  |  | 			stats.storageEngine = results.serverStatus.storageEngine ? results.serverStatus.storageEngine.name : 'mmapv1'; | 
					
						
							|  |  |  | 			stats.host = results.serverStatus.host; | 
					
						
							|  |  |  | 			stats.version = results.serverStatus.version; | 
					
						
							|  |  |  | 			stats.uptime = results.serverStatus.uptime; | 
					
						
							| 
									
										
										
										
											2015-05-08 15:36:06 -04:00
										 |  |  | 			stats.mongo = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			callback(null, stats); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 13:51:45 -04:00
										 |  |  | 	module.close = function() { | 
					
						
							|  |  |  | 		db.close(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-02 16:19:30 -05:00
										 |  |  | }(exports)); |