Commit d3db5e2a authored by Evan Steinkerchner's avatar Evan Steinkerchner
Browse files

Added mongodb document store adapter

parent 02093758
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -149,6 +149,28 @@ or post.

All of which are optional except `type` with very logical default values.

### MongoDB

To use mongodb storage you must install the 'mongodb' pachage in npm

`npm install mongodb`

Once you've done that, your config section should look like:

``` json
{
  "type": "mongodb",
  "connectionUrl": "mongodb://localhost:27017/database"
}
```

You can also just set the environment variable for `DATABASE_URL` to your database connection url.

Unlike with postgres you do NOT have to create the table in your mongo database prior to running.

You can also set an `expire` option to the number of seconds to expire keys in.
This is off by default, but will constantly kick back expirations on each view or post.

### Memcached

To use memcached storage you must install the `memcache` package via npm
+88 −0
Original line number Diff line number Diff line


var MongoClient = require('mongodb').MongoClient,
    winston = require('winston');

var MongoDocumentStore = function (options) {
    this.expire = options.expire;
    this.connectionUrl = process.env.DATABASE_URl || options.connectionUrl;
};

MongoDocumentStore.prototype.set = function (key, data, callback, skipExpire) {
    var now = Math.floor(new Date().getTime() / 1000),
        that = this;

    this.safeConnect(function (err, db) {
        if (err)
            return callback(false);
        
        db.collection('entries').update({
            'entry_id': key,
            $or: [
                { expiration: -1 },
                { expiration: { $gt: now } }
            ]
        }, {
            'entry_id': key,
            'value': data,
            'expiration': that.expire && !skipExpire ? that.expire + now : -1
        }, {
            upsert: true
        }, function (err, existing) {
            if (err) {
                winston.error('error persisting value to mongodb', { error: err });
                return callback(false);
            }

            callback(true);
        });
    });
};

MongoDocumentStore.prototype.get = function (key, callback, skipExpire) {
    var now = Math.floor(new Date().getTime() / 1000),
        that = this;

    this.safeConnect(function (err, db) {
        if (err)
            return callback(false);
        
        db.collection('entries').findOne({
            'entry_id': key,
            $or: [
                { expiration: -1 },
                { expiration: { $gt: now } }
            ]
        }, function (err, entry) {
            if (err) {
                winston.error('error persisting value to mongodb', { error: err });
                return callback(false);
            }

            callback(entry === null ? false : entry.value);

            if (entry !== null && entry.expiration !== -1 && that.expire && !skipExpire) {
                db.collection('entries').update({
                    'entry_id': key
                }, {
                    $set: {
                        'expiration': that.expire + now
                    }
                }, function (err, result) { });
            }
        });
    });
};

MongoDocumentStore.prototype.safeConnect = function (callback) {
    MongoClient.connect(this.connectionUrl, function (err, db) {
        if (err) {
            winston.error('error connecting to mongodb', { error: err });
            callback(err);
        } else {
            callback(undefined, db);
        }
    });
};

module.exports = MongoDocumentStore;