Files
NodeBB/src/database/mongo.js

248 lines
6.9 KiB
JavaScript
Raw Normal View History

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
var winston = require('winston');
var async = require('async');
var nconf = require('nconf');
var session = require('express-session');
var _ = require('underscore');
var semver = require('semver');
var meta = require('../meta');
var db;
2013-12-09 14:16:04 -05:00
_.mixin(require('underscore.deep'));
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',
description: 'MongoDB username',
'default': nconf.get('mongo:username') || ''
},
{
name: 'mongo:password',
description: 'Password of your MongoDB database',
hidden: true,
2016-08-04 20:58:04 +03:00
default: nconf.get('mongo:password') || '',
before: function (value) { value = value || nconf.get('mongo:password') || ''; return value; }
},
{
name: "mongo:database",
description: "MongoDB database name",
'default': nconf.get('mongo:database') || 'nodebb'
}
];
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');
module.init = function (callback) {
callback = callback || function () { };
var mongoClient;
try {
mongoClient = require('mongodb').MongoClient;
} 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-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
}
// 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', 'nodebb');
}
var hosts = nconf.get('mongo:host').split(',');
var ports = nconf.get('mongo:port').toString().split(',');
var servers = [];
2015-04-27 11:08:58 -07:00
for (var i = 0; i < hosts.length; i++) {
servers.push(hosts[i] + ':' + ports[i]);
}
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
}
};
connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions);
mongoClient.connect(connString, connOptions, function (err, _db) {
2014-10-30 22:19:11 -04:00
if (err) {
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 13:36:44 -05:00
2013-12-06 14:34:25 -05:00
db = _db;
module.client = db;
2015-04-01 12:28:01 -04: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) {
return callback(err);
2013-12-06 14:31:11 -05:00
}
callback();
2013-12-05 21:07:35 -05:00
});
2013-12-06 14:34:25 -05:00
} else {
winston.warn('You have no mongo password setup!');
2016-12-08 23:51:56 +03:00
callback();
}
2016-12-08 23:51:56 +03:00
});
};
module.initSessionStore = function (callback) {
var meta = require('../meta');
var sessionStore;
if (nconf.get('redis')) {
sessionStore = require('connect-redis')(session);
var rdb = require('./redis');
rdb.client = rdb.connect();
var ttlDays = 1000 * 60 * 60 * 24 * (parseInt(meta.config.loginDays, 10) || 14);
module.sessionStore = new sessionStore({
client: rdb.client,
ttl: ttlDays
});
} else if (nconf.get('mongo')) {
sessionStore = require('connect-mongo')(session);
module.sessionStore = new sessionStore({
db: db
});
}
callback();
};
2016-12-09 00:00:29 +03:00
module.createIndices = function (callback) {
2016-12-08 23:51:56 +03:00
function createIndex(collection, index, options, callback) {
module.client.collection(collection).createIndex(index, options, callback);
2016-12-08 23:51:56 +03:00
}
if (!module.client) {
winston.warn('[database/createIndices] database not initialized');
return callback();
}
2015-12-11 10:57:13 +02:00
2016-12-08 23:51:56 +03:00
winston.info('[database] Checking database indices.');
async.series([
async.apply(createIndex, 'objects', { _key: 1, score: -1 }, { background: true }),
async.apply(createIndex, 'objects', { _key: 1, value: -1 }, { background: true, unique: true, sparse: true }),
async.apply(createIndex, 'objects', { expireAt: 1 }, { expireAfterSeconds: 0, background: true })
2016-12-08 23:51:56 +03:00
], function (err) {
if (err) {
winston.error('Error creating index ' + err.message);
return callback(err);
2015-12-11 10:57:13 +02:00
}
2016-12-08 23:51:56 +03:00
winston.info('[database] Checking database indices done!');
callback();
});
2014-03-01 16:59:04 -05:00
};
2013-12-02 22:48:32 -05:00
module.checkCompatibility = function (callback) {
2016-12-08 23:51:56 +03:00
var mongoPkg = require.main.require('./node_modules/mongodb/package.json');
2016-12-09 00:18:25 +03:00
if (semver.lt(mongoPkg.version, '2.0.0')) {
return callback(new Error('The `mongodb` package is out-of-date, please run `./nodebb setup` again.'));
2015-06-05 13:33:58 -04:00
}
2016-12-09 00:18:25 +03:00
callback();
2015-06-05 13:33:58 -04:00
};
module.info = function (db, callback) {
2016-11-23 17:15:31 +03:00
if (!db) {
return callback();
}
2015-08-12 16:14:48 -04:00
async.parallel({
serverStatus: function (next) {
db.command({ 'serverStatus': 1 }, next);
2015-08-12 16:14:48 -04:00
},
stats: function (next) {
db.command({ 'dbStats': 1 }, next);
2015-10-17 18:26:03 -04:00
},
listCollections: function (next) {
db.listCollections().toArray(function (err, items) {
2015-10-17 18:26:03 -04:00
if (err) {
return next(err);
}
async.map(items, function (collection, next) {
2015-10-17 18:26:03 -04:00
db.collection(collection.name).stats(next);
}, next);
});
2015-08-12 16:14:48 -04:00
}
}, function (err, results) {
2015-08-12 16:14:48 -04:00
if (err) {
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;
results.listCollections = results.listCollections.map(function (collectionInfo) {
2015-10-17 18:34:04 -04:00
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;
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;
stats.mongo = true;
callback(null, stats);
});
};
module.close = function () {
2014-04-14 13:51:45 -04:00
db.close();
};
} (exports));