2020-08-27 00:42:48 +02:00
|
|
|
const winston = require('winston');
|
|
|
|
const mongodb = require('mongodb');
|
|
|
|
|
2020-09-02 16:16:54 +02:00
|
|
|
class MongoDocumentStore {
|
|
|
|
constructor(config){
|
|
|
|
this.expire = config.expire;
|
|
|
|
this.MongoClient = new mongodb.MongoClient(config.connectionUri, config.clientOptions);
|
|
|
|
}
|
2020-08-27 00:42:48 +02:00
|
|
|
|
2020-09-02 16:16:54 +02:00
|
|
|
async set(key, data, callback, skipExpire){
|
|
|
|
winston.silly(`mongo set ${key}`);
|
|
|
|
const now = Math.floor(Date.now() / 1000);
|
|
|
|
const that = this;
|
2020-08-27 00:42:48 +02:00
|
|
|
|
2020-09-03 19:24:34 +02:00
|
|
|
if ((await this.safeConnect()).error) return false;
|
2020-08-27 00:42:48 +02:00
|
|
|
|
2020-09-02 16:16:54 +02:00
|
|
|
return await this.MongoClient.db().collection('entries').updateOne(
|
2020-08-27 00:42:48 +02:00
|
|
|
{
|
|
|
|
'entry_id': key,
|
|
|
|
$or: [
|
|
|
|
{ expiration: -1 },
|
|
|
|
{ expiration: { $gt: now } }
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
$set: {
|
|
|
|
'entry_id': key,
|
|
|
|
value: data,
|
|
|
|
expiration: that.expire && !skipExpire ? that.expire + now : -1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
upsert: true
|
|
|
|
}
|
2020-08-28 04:39:03 +02:00
|
|
|
)
|
|
|
|
.then((err, result) => {
|
2020-09-02 16:16:54 +02:00
|
|
|
return true;
|
2020-08-28 04:39:03 +02:00
|
|
|
})
|
|
|
|
.catch((err, result) => {
|
|
|
|
winston.error('error updating mongodb document', { error: err });
|
2020-09-02 16:16:54 +02:00
|
|
|
return false;
|
2020-08-28 04:39:03 +02:00
|
|
|
});
|
2020-09-02 16:16:54 +02:00
|
|
|
}
|
|
|
|
async get(key, skipExpire){
|
|
|
|
winston.silly(`mongo get ${key}`);
|
|
|
|
const now = Math.floor(Date.now() / 1000);
|
|
|
|
const that = this;
|
2020-08-27 00:42:48 +02:00
|
|
|
|
2020-09-02 16:16:54 +02:00
|
|
|
if ((await this.safeConnect()).error) return null;
|
2020-08-27 00:42:48 +02:00
|
|
|
|
|
|
|
let document = await this.MongoClient.db().collection('entries').findOne({
|
|
|
|
'entry_id': key,
|
2020-08-28 04:39:03 +02:00
|
|
|
$or: [
|
2020-08-27 00:42:48 +02:00
|
|
|
{ expiration: -1 },
|
|
|
|
{ expiration: { $gt: now } }
|
|
|
|
]
|
2020-09-02 16:16:54 +02:00
|
|
|
}).catch(err => {
|
|
|
|
winston.error('error finding mongodb document', { error: err });
|
|
|
|
return null;
|
|
|
|
});
|
2020-08-27 00:42:48 +02:00
|
|
|
|
2020-09-02 16:16:54 +02:00
|
|
|
if (document && document.expiration != -1 && that.expire && !skipExpire) {
|
2020-08-27 00:42:48 +02:00
|
|
|
await this.MongoClient.db().collection('entries').updateOne(
|
|
|
|
{ 'entry_id': key },
|
|
|
|
{ $set: { expiration: that.expire + now } }
|
|
|
|
).catch(err => {
|
|
|
|
return winston.warn('error extending expiry of mongodb document', { error: err });
|
|
|
|
});
|
2020-08-28 04:39:03 +02:00
|
|
|
winston.silly('extended expiry of mongodb document', { key: key, timestamp: that.expire + now });
|
2020-08-27 00:42:48 +02:00
|
|
|
}
|
2020-09-02 16:16:54 +02:00
|
|
|
return document ? document.value : null;
|
|
|
|
}
|
2020-09-03 19:24:34 +02:00
|
|
|
async safeConnect(){
|
2020-09-02 16:16:54 +02:00
|
|
|
//don't try connecting again if already connected
|
|
|
|
//https://jira.mongodb.org/browse/NODE-1868
|
|
|
|
if (this.MongoClient.isConnected()) return { error: null };
|
2020-09-03 19:24:34 +02:00
|
|
|
return await this.MongoClient.connect()
|
|
|
|
.then(() => {
|
|
|
|
winston.info('connected to mongodb');
|
2020-09-02 16:16:54 +02:00
|
|
|
return { error: null };
|
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
winston.error('error connecting to mongodb', { error: err });
|
|
|
|
return { error: err };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-08-27 00:42:48 +02:00
|
|
|
|
|
|
|
|
2020-09-03 19:24:34 +02:00
|
|
|
module.exports = MongoDocumentStore;
|