UNPKG

gracenode-mongodb

Version:
122 lines (108 loc) 3.22 kB
var mongodb = require('mongodb'); var async = require('async'); var gracenode = require('../gracenode'); var logger = gracenode.log.create('mongodb'); var Db = require('./db'); var options = [ 'poolSize', 'replicaSet', 'readPreference', 'slaveOk' ]; var config = null; var pools = {}; /* "mongodb": { "name of your choice": { "host": "host name or ip address" or an array of hosts, "port": port number or an array of port numbers, "database": "database name", "user": "db user", // optional "password": "db password" // optional, "poolSize": <int>, // optional default is 5 "replicaSet": "target replicaset name" optional "readPreference": "read preference (secondary etc)" optional, "slaveOk": <boolean> optional } {...} } */ module.exports.readConfig = function (configIn) { if (!configIn) { return new Error('invalid configurations given:\n' + JSON.stringify(configIn)); } config = configIn; }; module.exports.setup = function (cb) { var keys = Object.keys(config); var client = mongodb.MongoClient; async.eachSeries(keys, function (name, next) { var configData = config[name]; var url = 'mongodb://'; var glue = '?'; // use user and password if (configData.user && configData.password) { url += configData.user + ':' + configData.password + '@'; } if (Array.isArray(configData.host)) { // connecting to multiple mongo var isPortArray = Array.isArray(configData.port); for (var i = 0, len = configData.host.length; i < len; i++) { url += configData.host[i] + ((isPortArray && configData.port[i]) ? ':' + configData.port[i] : ''); var end = ','; if (i === len - 1) { end = '/'; } url += end; } url += configData.database; } else { // connecting to a single mongo url += configData.host + ':' + configData.port + '/' + configData.database; } url += createOptionParams(configData); logger.verbose('creating connection pool to mongodb [' + configData.database + ']:', url); client.connect(url, function (error, db) { if (error) { return cb(error); } pools[name] = { db: db, database: configData.database }; logger.info('connection pool to mongodb created [' + configData.database + ']'); next(); }); }, function () { // register graceful exit cleaner gracenode.registerShutdownTask('mongodb', function (done) { var names = Object.keys(pools); async.eachSeries(names, function (name, next) { pools[name].db.close(function (error) { if (error) { logger.error('failed to close connection to mongodb [' + pools[name].database + ']', error); } logger.info('connection pool to mongodb closed [' + pools[name].database + ']'); delete pools[name]; next(); }); }, done); }); // all is done cb(); }); }; module.exports.create = function (name) { if (pools[name]) { return new Db(pools[name].database, pools[name].db); } return null; }; function createOptionParams(configData) { var params = ''; var glue = '?'; for (var i = 0, len = options.length; i < len; i++) { if (configData.hasOwnProperty(options[i])) { params += glue + options[i] + '=' + configData[options[i]]; glue = '&'; } } return params; }