UNPKG

happn-service-mongo-2

Version:

service plugin for running happn on a mongo database, for happn-3 instances

153 lines (127 loc) 4.14 kB
const mongodb = require('mongodb'), mongoclient = mongodb.MongoClient, util = require('util'); MongoDataStore.prototype.ObjectID = mongodb.ObjectId; MongoDataStore.prototype.initialize = util.promisify(initialize); MongoDataStore.prototype.findOne = util.promisify(findOne); MongoDataStore.prototype.count = util.promisify(count); MongoDataStore.prototype.aggregate = util.promisify(aggregate); MongoDataStore.prototype.find = util.promisify(find); MongoDataStore.prototype.increment = util.promisify(increment); MongoDataStore.prototype.insert = util.promisify(insert); MongoDataStore.prototype.update = util.promisify(update); MongoDataStore.prototype.findAndModify = util.promisify(findAndModify); MongoDataStore.prototype.remove = util.promisify(remove); MongoDataStore.prototype.disconnect = util.promisify(disconnect); function MongoDataStore(config) { if (!config.database) config.database = 'happn'; if (!config.collection) config.collection = 'happn'; if (!config.policy) config.policy = {}; if (!config.opts) config.opts = {}; config.opts.useNewUrlParser = true; config.opts.useUnifiedTopology = true; Object.defineProperty(this, 'config', { value: config }); } function initialize(callback) { mongoclient.connect(this.config.url, this.config.opts, (err, client) => { if (err) return callback(err); let db = client.db(this.config.database); let collection = db.collection(this.config.collection); Object.defineProperty(this, 'data', { value: collection }); Object.defineProperty(this, 'connection', { value: client }); return callback(); }); } function findOne(criteria, fields, callback) { return this.data.findOne(criteria, fields, callback); } function count(criteria, options, callback) { return this.data.countDocuments(criteria, options, callback); } function aggregate(criteria, pipeline, options, callback) { pipeline.unshift({ $match: criteria }); return this.data.aggregate(pipeline, options).toArray(callback); } function find(criteria, searchOptions, sortOptions, callback) { if (searchOptions.projection) { //always return the path and _id for _meta searchOptions.projection.path = 1; searchOptions.projection._id = 1; } let maxTimeMS = searchOptions.maxTimeMS || 0; delete searchOptions.maxTimeMS; if (!sortOptions) return this.data .find(criteria, searchOptions) .maxTimeMS(maxTimeMS) .toArray(callback); this.data .find(criteria, searchOptions) .maxTimeMS(maxTimeMS) .sort(sortOptions) .toArray(callback); } function increment(path, counterName, increment, callback) { let setParameters = { $inc: {} }; setParameters.$inc['data.' + counterName + '.value'] = increment; this.update( { path: path }, setParameters, (e, updated) => { if (e) return callback(e); callback(null, updated.data[counterName].value); } ); } function insert(data, options, callback) { return this.data.insertOne(data, options, callback); } function update(criteria, data, options, callback) { if (typeof options == 'function') { callback = options; options = {}; } if (!options) options = {}; options.upsert = true; options.returnDocument = 'after'; return this.data.findOneAndUpdate(criteria, data, options, function(e, item) { if (e) return callback(e); if (item) return callback(null, item.value); callback(null, null); }); } function findAndModify(criteria, data, callback) { return this.update(criteria, data, callback); } function remove(criteria, callback) { return this.data.deleteMany(criteria, callback); } function disconnect(callback) { try { if (this.connection) return this.connection.close(callback); } catch (e) { console.warn('failed disconnecting mongo client', e); } callback(); } module.exports.create = util.promisify(function(config, callback) { try { let store = new MongoDataStore(config); store.initialize(function(e) { if (e) return callback(e); callback(null, store); }); } catch (e) { callback(e); } });