red-mongo

MongoDb wrapper for nodejs inspired by mongoose

npm install red-mongo
4 downloads in the last month

red-mongo

A mongodb wrapper for node.js inspired by mongoose.

The specificity of this wrapper is to use a singleton to give you access to your database across all your application files using a single connection. Plus some useful functions to ease your everyday life.

Usage:

After the usual install:

> npm install red-mongo

You'll then need to setup your singleton by indicating the server you want to connect to and the collections you want to use. Collections are pre-loaded on connection init to avoid future overhead. You get to define the collection name inside the library, its "prettyName" for use inside your app and possible indexes to ensure.

Using any name reserved by the singleton for its methods as a "prettyName" will return an error. This is the only case you can get an error triggered by red-mongo itself and not mongodb.

// The server address can be an URI or a Server object
var server = process.env.MONGODB_URI;

// You need to pass your collections as an array
var collections = [
  {
    // "collection" is the collection name on the database
    collection: 'users',
    // "prettyName" is the name to access it from your app
    prettyName: 'User',
    // Indexes must be given as an array
    indexes: [
      {
        name: 'login',
        rule: { username: 1 },
        opts: { unique: true, sparse: false }
      },
      {
        name: 'creation_date',
        rule: { created_on: 1 },
        opts: { unique: false, sparse: false }
      }
    ]
  },
  {
    // If no indexes, just omit the field
    collection: 'files',
    prettyName: 'File'
  }
];

// Connect to the database
var RedMongo = require('red-mongo');
RedMongo.connect(server, collections, function (err) {
  if (err) return console.dir(err);
  // Now you can successfully make calls accross your app
});

You now have a singleton! If you want to make a mongodb call from another file, just require() the module to access your singleton:

var RedMongo = require('red-mongo');
RedMongo.User.findOne({}, function (err, user) {
  if (err) return console.dir(err);
  if (!user) return console.log('No user');
  console.dir(user);
});

For clarity and (writing) speed, a wrapper is automatically added to all your collections: .findAll(). This method works EXACTLY like the Collection.find() you've grown to love (and/or hate) except you get your results straight without having to call Cursor.toArray() by yourself.

var RedMongo = require('red-mongo');
RedMongo.User.findAll({}, function (err, users) {
  if (err) return console.dir(err);
  if (!user) return console.log('No user');
  console.log('Found %d users!', users.length);
});

Helper methods:

Some functions have been attached to the singleton to ease your life.

RedMongo.isConnected ()

Returns a boolean telling you if your singleton is connected to a database.

RedMongo.makeObjectId (hexstring)

Takes a stringified ObjectId and returns an ObjectId object, or null if the passed string isn't a valid ObjectId string.

RedMongo.makeObjectId('red');
> null
RedMongo.makeObjectId('D34DC4F3D34DC4F3D34DC4F3');
> d34dc4f3d34dc4f3d34dc4f3

RedMongo.checkObjectId (hexstring)

Takes a stringified ObjectId and returns a boolean depending on whether this string is a valid ObjectId string or not.

RedMongo.checkObjectId('red');
> false
RedMongo.checkObjectId('D34DC4F3D34DC4F3D34DC4F3');
> true

RedMongo.errLog (...)

Return a callback function for quick logging of non-critical MongoDb errors. You may pass any arguments you want, they will be formatted printf-style with require('util').format() and will be output in case of error as an indiciation of what fired the error.

var query = { login: 'red' };
var mod = { $set: { last_visit: new Date() } };
var cb = RedMongo.errLog('Updating last_visit for %s', query.login);
RedMongo.User.update(query, mod, cb);
> [MongoDb] Error on: Updating last_visit for red
> (Full dump of error object)

RedMongo.parallelCalls (size, options, callback)

Parallel MongoDb request creator. Created with the number of requests to parallelize, an optional object of options and the callback function to be called once all requests are done. Results are passed to this callback in the standard "error first, results last" model. Only change is that this time the result is an object of results.

Deprecated for now, you should use [caolan's async library] (https://github.com/caolan/async) instead. If you really don't want to use async for whatever reason and really think using this would be better for you, you're free to read the instructions either in the source code or in this file's previous commit.

RedMongo.getFields (fields [, unfields])

Takes two array of strings describing the fields to include or exclude from a query an returns a mongodb-compatible object.

var query = { login: 'red' };
var fields = RedMongo.getFields(['login', 'age'], ['_id']);
console.dir(fields);
> { "login": 1, "age": 1, "_id": 0 }
RedMongo.User.findOne(query, fields, function (err, user) {
  if (err) return console.dir(err);
  if (!user) return console.log('No red');
  console.dir(user);
  > { "login": "red", "age": 25 }
});

Other available uses:

// With a single string in included fields
console.dir(RedMongo.getFields('login'));
> { "login": 1 }

// No included fields, but a string for excluded fields
console.dir(RedMongo.getFields(null, '_id'));
> { "_id": 0 }

// No fields
console.dir(RedMongo.getFields());
> { }

RedMongo.middleware (view)

Just in case things go south with your database (or someone tries to access your app before the database connection is done) and your app can't process the request, pass along the view you want to render to indicate something's wrong to your visitors.

var app = require('express')();
app.use(RedMongo.middleware('mongodb-error'));

Only supports ServerResponse.render() for now. But if you look at the source, it shouldn't be too hard to write your own middleware to return a JSON-formatted error if an users connects and the database can't be accessed.

TODO:

  • Grow up and make the .findAll() wrapper native to the Collection (or the RedCollection?) prototype (monkey-patching and overloading is sexy, right?).
  • Unit tests
  • Make parallelCalls more professional to use and look at
  • Handle disconnections cases (never happened to me so far, so never bothered with it).
  • Add more options to the singleton creation (load config from a file?).
  • Add more options to the middleware.
  • Add express SessionStore support.

License

Copyright (c) 2013, Arnaud "JoshLeaves" ROUYER

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of red-mongo nor the names of its contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

npm loves you