2014-06-09 18:48:35 +00:00
|
|
|
/*global require,module,process*/
|
|
|
|
|
|
|
|
var winston = require('winston');
|
2020-10-07 00:52:48 +00:00
|
|
|
const {Client} = require('pg');
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-27 22:40:05 +00:00
|
|
|
// create table entries (id serial primary key, key varchar(255) not null, value text not null, expiration int, unique(key));
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
// A postgres document store
|
|
|
|
var PostgresDocumentStore = function (options) {
|
|
|
|
this.expireJS = options.expire;
|
|
|
|
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl;
|
|
|
|
};
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
PostgresDocumentStore.prototype = {
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
// Set a given key
|
|
|
|
set: function (key, data, callback, skipExpire) {
|
|
|
|
var now = Math.floor(new Date().getTime() / 1000);
|
|
|
|
var that = this;
|
|
|
|
this.safeConnect(function (err, client, done) {
|
|
|
|
if (err) { return callback(false); }
|
|
|
|
client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [
|
|
|
|
key,
|
|
|
|
data,
|
|
|
|
that.expireJS && !skipExpire ? that.expireJS + now : null
|
2017-06-26 16:19:36 +00:00
|
|
|
], function (err) {
|
2014-06-09 20:50:43 +00:00
|
|
|
if (err) {
|
|
|
|
winston.error('error persisting value to postgres', { error: err });
|
|
|
|
return callback(false);
|
|
|
|
}
|
|
|
|
callback(true);
|
|
|
|
done();
|
2014-06-09 18:48:35 +00:00
|
|
|
});
|
2014-06-09 20:50:43 +00:00
|
|
|
});
|
|
|
|
},
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
// Get a given key's data
|
|
|
|
get: function (key, callback, skipExpire) {
|
|
|
|
var now = Math.floor(new Date().getTime() / 1000);
|
|
|
|
var that = this;
|
|
|
|
this.safeConnect(function (err, client, done) {
|
|
|
|
if (err) { return callback(false); }
|
|
|
|
client.query('SELECT id,value,expiration from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now], function (err, result) {
|
2014-06-09 18:48:35 +00:00
|
|
|
if (err) {
|
2014-06-09 20:50:43 +00:00
|
|
|
winston.error('error retrieving value from postgres', { error: err });
|
|
|
|
return callback(false);
|
|
|
|
}
|
|
|
|
callback(result.rows.length ? result.rows[0].value : false);
|
|
|
|
if (result.rows.length && that.expireJS && !skipExpire) {
|
|
|
|
client.query('UPDATE entries SET expiration = $1 WHERE ID = $2', [
|
|
|
|
that.expireJS + now,
|
|
|
|
result.rows[0].id
|
2017-06-26 16:19:36 +00:00
|
|
|
], function (err) {
|
2014-06-09 20:50:43 +00:00
|
|
|
if (!err) {
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
});
|
2014-06-09 18:48:35 +00:00
|
|
|
} else {
|
2014-06-09 20:50:43 +00:00
|
|
|
done();
|
2014-06-09 18:48:35 +00:00
|
|
|
}
|
|
|
|
});
|
2014-06-09 20:50:43 +00:00
|
|
|
});
|
|
|
|
},
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
// A connection wrapper
|
|
|
|
safeConnect: function (callback) {
|
2020-10-07 00:52:48 +00:00
|
|
|
const client = new Client({connectionString: this.connectionUrl});
|
|
|
|
const connectionPromise = client.connect();
|
|
|
|
|
|
|
|
const done = () => {};
|
|
|
|
|
|
|
|
connectionPromise.then(() => {
|
|
|
|
callback(undefined, client, done);
|
|
|
|
}).catch((error) => {
|
|
|
|
console.log(error);
|
|
|
|
winston.error('error connecting to postgres', {error});
|
|
|
|
callback(error);
|
2014-06-09 20:50:43 +00:00
|
|
|
});
|
|
|
|
}
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
};
|
2014-06-09 18:48:35 +00:00
|
|
|
|
2014-06-09 20:50:43 +00:00
|
|
|
module.exports = PostgresDocumentStore;
|