I am working on a nodejs / mongodb app using 'mongodb' module. The app is launched with
我正在使用'mongodb'模块处理nodejs / mongodb应用程序。该应用程序启动
node main.js
In main.js, I connect to the db and keep the connection in the 'db' global variable. 'db' is then used in inner methods of 'server'. I want to avoid having 'db' as a global variable but did not found the correct way to do.
在main.js中,我连接到db并将连接保存在'db'全局变量中。然后'db'用在'server'的内部方法中。我想避免将'db'作为全局变量,但没有找到正确的方法。
My current main.js:
我目前的main.js:
var server = require('./lib/server');
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
var mongoClient = new MongoClient(new Server(HOST, PORT));
db = null;
// Database connection
mongoClient.open(function(err, mongoClient) {
if(!err){
// Database selection
db = mongoClient.db(DB);
// Launch web server
server.start(); // usage of 'db' in this part
} else {
console.log(err.message);
process.exit(1);
}
});
Any idea of a cleaner way ?
想要更清洁的方法吗?
UPDATE
UPDATE
I finally created a module in connection.js:
我终于在connection.js中创建了一个模块:
var config = require('../config/config');
var url = 'mongodb://' + config.db.host + ':' + config.db.port + '/' + config.db.name;
var MongoClient = require('mongodb').MongoClient;
var db = null;
module.exports = function(cb){
if(db){
cb(db);
return;
}
MongoClient.connect(url, function(err, conn) {
if(err){
console.log(err.message);
throw new Error(err);
} else {
db = conn;
cb(db);
}
});
}
Each time I need to get the connection I call:
每次我需要连接时我都会打电话:
var connection = require('./connection');
connection(function(db){
// doing some stuff with the db
});
This is working very well.
这非常有效。
Any potential failure with this approach ?
这种方法有任何潜在的失败吗?
2 个解决方案
#1
6
I typically include a project utilities file that contains a number of these things, just to make it easy. It functions as a pseudo global, but without many of the usual problems globals entail.
我通常包含一个项目实用程序文件,其中包含许多这些内容,只是为了方便起见。它起到伪全局的作用,但没有全局性所带来的许多常见问题。
For example,
例如,
projectUtils.js
projectUtils.js
module.exports = {
initialize: function(next){
// initialization actions, there can be many of these
this.initializeDB(next);
},
initializeDb: function(next){
mongoClient.open(function(err, mongoClient) {
if(err) return next(err);
module.exports.db = mongoClient.db(DB);
next();
});
}
}
app.js
app.js
var projectUtils = require('projectUtils');
// (snip)
projectUtils.initialize(function(err) {
if(err) throw err; // bad DB initialization
// After this point and inside any of your routes,
// projectUtils.db is available for use.
app.listen(port);
}
By using an asynchronous initialize() function, you can be sure that all database connections, file I/O, etc., are done before starting up the server.
通过使用异步initialize()函数,您可以确保在启动服务器之前完成所有数据库连接,文件I / O等。
#2
3
You can create a wrapper something like a provider and put it in provider.js, for instance.
例如,您可以创建类似提供程序的包装器并将其放在provider.js中。
Provider = function (db_name, host, port, username, password) {
var that = this;
var conn = generate_url(db_name, host, port, username, password); // you need to implement your version of generate_url()
MongoClient.connect(conn, function (err, db) {
if (err) {
throw err;
}
that.db = db;
});
};
//add the data access functions
Provider.prototype.getCollection = function (collectionName, callback) {
this.db.collection(collectionName, collectionOptions, callback);
};
exports.Provider = Provider;
This is how you use the provider:
这是您使用提供程序的方式:
var db = new Provider(db_name, host, port, username, password);
db.getCollection('collection name', callback);
#1
6
I typically include a project utilities file that contains a number of these things, just to make it easy. It functions as a pseudo global, but without many of the usual problems globals entail.
我通常包含一个项目实用程序文件,其中包含许多这些内容,只是为了方便起见。它起到伪全局的作用,但没有全局性所带来的许多常见问题。
For example,
例如,
projectUtils.js
projectUtils.js
module.exports = {
initialize: function(next){
// initialization actions, there can be many of these
this.initializeDB(next);
},
initializeDb: function(next){
mongoClient.open(function(err, mongoClient) {
if(err) return next(err);
module.exports.db = mongoClient.db(DB);
next();
});
}
}
app.js
app.js
var projectUtils = require('projectUtils');
// (snip)
projectUtils.initialize(function(err) {
if(err) throw err; // bad DB initialization
// After this point and inside any of your routes,
// projectUtils.db is available for use.
app.listen(port);
}
By using an asynchronous initialize() function, you can be sure that all database connections, file I/O, etc., are done before starting up the server.
通过使用异步initialize()函数,您可以确保在启动服务器之前完成所有数据库连接,文件I / O等。
#2
3
You can create a wrapper something like a provider and put it in provider.js, for instance.
例如,您可以创建类似提供程序的包装器并将其放在provider.js中。
Provider = function (db_name, host, port, username, password) {
var that = this;
var conn = generate_url(db_name, host, port, username, password); // you need to implement your version of generate_url()
MongoClient.connect(conn, function (err, db) {
if (err) {
throw err;
}
that.db = db;
});
};
//add the data access functions
Provider.prototype.getCollection = function (collectionName, callback) {
this.db.collection(collectionName, collectionOptions, callback);
};
exports.Provider = Provider;
This is how you use the provider:
这是您使用提供程序的方式:
var db = new Provider(db_name, host, port, username, password);
db.getCollection('collection name', callback);