diff --git a/README.md b/README.md index 3925a0d..cc09acc 100644 --- a/README.md +++ b/README.md @@ -174,12 +174,13 @@ Once you've done that, your config section should look like: ``` json { - "type": "mongo", - "connectionUrl": "mongodb://localhost:27017/database" + "type": "mongodb", + "connectionUrl": "mongodb://localhost:27017", + "connectionName": "database" } ``` -You can also just set the environment variable for `DATABASE_URL` to your database connection url. +You can also just set the environment variable for `DATABASE_URL` to your server connection url and `DATABASE_NAME` for your database name. Unlike with postgres you do NOT have to create the table in your mongo database prior to running. diff --git a/lib/document_stores/mongo.js b/lib/document_stores/mongo.js deleted file mode 100644 index 502a508..0000000 --- a/lib/document_stores/mongo.js +++ /dev/null @@ -1,88 +0,0 @@ - - -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; diff --git a/lib/document_stores/mongodb.js b/lib/document_stores/mongodb.js new file mode 100644 index 0000000..0f4ac03 --- /dev/null +++ b/lib/document_stores/mongodb.js @@ -0,0 +1,110 @@ +const { MongoClient } = require("mongodb"), + winston = require("winston"); + +const MongoDocumentStore = function (options) { + this.expire = options.expire; + this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl; + this.connectionName = process.env.DATABASE_NAME || options.connectionName; +}; + +MongoDocumentStore.prototype.set = function (key, data, callback, skipExpire) { + const now = Math.floor(new Date().getTime() / 1000); + + this.safeConnect((err, db, client) => { + if (err) return callback(false); + + db.collection("entries").updateOne( + { + entry_id: key, + $or: [{ expiration: -1 }, { expiration: { $gt: now } }], + }, + { + $set: { + entry_id: key, + value: data, + expiration: + this.expire && !skipExpire ? this.expire + now : -1, + }, + }, + { + upsert: true, + }, + (err /*, existing*/) => { + client.close(); + + if (err) { + winston.error("error persisting value to mongodb", { + error: err, + }); + return callback(false); + } + + callback(true); + } + ); + }); +}; + +MongoDocumentStore.prototype.get = function (key, callback, skipExpire) { + const now = Math.floor(new Date().getTime() / 1000); + + this.safeConnect((err, db, client) => { + if (err) return callback(false); + + db.collection("entries").findOne( + { + entry_id: key, + $or: [{ expiration: -1 }, { expiration: { $gt: now } }], + }, + (err, entry) => { + if (err) { + winston.error("error persisting value to mongodb", { + error: err, + }); + client.close(); + return callback(false); + } + + callback(entry === null ? false : entry.value); + + if ( + entry !== null && + entry.expiration !== -1 && + this.expire && + !skipExpire + ) { + db.collection("entries").updateOne( + { + entry_id: key, + }, + { + $set: { + expiration: this.expire + now, + }, + }, + () => { + client.close(); + } + ); + } + } + ); + }); +}; + +MongoDocumentStore.prototype.safeConnect = function (callback) { + MongoClient.connect( + this.connectionUrl, + { useUnifiedTopology: true }, + (err, client) => { + if (err) { + winston.error("error connecting to mongodb", { error: err }); + callback(err); + } else { + callback(undefined, client.db(this.connectionName), client); + } + } + ); +}; + +module.exports = MongoDocumentStore;