db.open(function(err,db){
//handle error
db.collection("book",function(err, collection){
//handle error
collection.doSomething1(... function(err, result){
//handle error
collection.doSomething2(... function(err, result){
...
})
})
})
})
but we wont wrote db.open every time when we want do something, but we must make sure that db has opened when we use it.
we still wont like handle error every time in the same code.
we can also reuse the collection.
just like this
errorHandledDB.doSomething1("book",... function(result){
errorHandledDB.doSomething2("book",...function(result){
...
})
})
I implemented a server-application using mongodb for logging. I implemented data access using some provider classes, as shown in the example.
provider.filelog.js
var Db= require('mongodb/db').Db,
ObjectID= require('mongodb/bson/bson').ObjectID,
Server= require('mongodb/connection').Server,
log = require('lib/common').log;
FilelogProvider = function (host, port, database) {
this.db= new Db(database, new Server(host, port, {auto_reconnect: true}, {}));
this.db.open(function(){});
};
FilelogProvider.prototype.getCollection= function(callback) {
this.db.collection('filelogs', function(error, log_collection) {
if (error) callback(error);
else {
log_collection.ensureIndex([[ 'created', 1 ]], false, function(err, indexName) {
if (error) callback(error);
callback(null, log_collection);
});
}
});
};
FilelogProvider.prototype.findAll = function(callback) {
this.getCollection(function(error, log_collection) {
if (error) callback(error);
else {
log_collection.find(function(error, cursor) {
if (error) callback(error);
else {
cursor.toArray(function(error, results) {
if (error) callback(error);
else callback(null, results);
});
}
});
}
});
};
Since i use Grasshopper as my http-middleware, i can easily inject the providers using the DI functionality provided by gh:
server.js
gh.addToContext({
providers: {
filelog: new FilelogProvider(conf.mongodb_host, conf.mongodb_port, conf.mongodb_database),
status: new ServerstatusProvider(conf.mongodb_host, conf.mongodb_port, conf.mongodb_database)
},
log: log
});
Accessing the providers in every controller function is now a breeze:
gh.get('/serve', function() {
this.providers.filelog.findAll(function(err, res) {
// access data here
});
});
This implementation is pretty specific to Grasshopper (as it's using DI) but i think you'll get the idea. I also implemented a solution using express and mongoose, you find it here. This solution is a bit cleaner than using the native driver, as it exposes models to use against the database.
Just for the sake of it: if you really want to stick to the DRY-principle, stop tinkering on an ORM implementation yourself and use Mongoose. If you need special functionality like Map/Reduce, you still can use the native driver (on which Mongoose is built).
Answer my own question. Because there is no more good options, I do it myself, I start a project to simplify it, check node-mongoskin.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With