1
0
Fork 0
mirror of https://github.com/SunRed/haste-server.git synced 2025-09-04 04:50:14 +02:00

Rewritten postgresql document store

This is experimental as there are couple issues with attemting to set duplicate keys and connecting on startup, but it's working regardless of those issues.\nMaybe I can look into solving those later if needed
This commit is contained in:
zneix 2020-09-03 19:24:34 +02:00
parent e3e45bee3c
commit 7d476a668e
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 911916E0523B22F6
5 changed files with 93 additions and 196 deletions

View file

@ -12,7 +12,7 @@ class MongoDocumentStore {
const now = Math.floor(Date.now() / 1000);
const that = this;
if ((await this.safeConnect()).error) return null;
if ((await this.safeConnect()).error) return false;
return await this.MongoClient.db().collection('entries').updateOne(
{
@ -70,13 +70,13 @@ class MongoDocumentStore {
}
return document ? document.value : null;
}
safeConnect(){
async safeConnect(){
//don't try connecting again if already connected
//https://jira.mongodb.org/browse/NODE-1868
if (this.MongoClient.isConnected()) return { error: null };
return this.MongoClient.connect()
.then(client => {
winston.debug('connected to mongodb', { success: true });
return await this.MongoClient.connect()
.then(() => {
winston.info('connected to mongodb');
return { error: null };
})
.catch(err => {
@ -89,4 +89,4 @@ class MongoDocumentStore {
module.exports = MongoDocumentStore;
module.exports = MongoDocumentStore;

View file

@ -1,80 +1,65 @@
// /*global require,module,process*/
const postgres = require('pg');
const winston = require('winston');
const postgres = require('pg');
// create table entries (id serial primary key, key varchar(255) not null, value text not null, expiration int, unique(key));
// A postgres document store
const PostgresDocumentStore = function (options){
this.expireJS = options.expire;
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl;
};
PostgresDocumentStore.prototype = {
// Set a given key
set: function (key, data, callback, skipExpire){
const now = Math.floor(Date.now() / 1000);
const 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
], function (err){
if (err){
winston.error('error persisting value to postgres', { error: err });
return callback(false);
}
callback(true);
done();
});
});
},
// Get a given key's data
get: function (key, callback, skipExpire){
const now = Math.floor(Date.now() / 1000);
const 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){
if (err){
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
], function (err){
if (!err){
done();
}
});
} else {
done();
}
});
});
},
// A connection wrapper
safeConnect: function (callback){
postgres.connect(this.connectionUrl, function (err, client, done){
if (err){
winston.error('error connecting to postgres', { error: err });
callback(err);
} else {
callback(undefined, client, done);
}
class PostgresDocumentStore {
constructor(options){
this.expire = options.expire;
this.PostgresClient = new postgres.Client(options.clientOptions);
this.safeConnect();
this.PostgresClient.on('end', () => {
winston.debug('disconnected from pg!');
});
}
};
async set(key, data, skipExpire){
const now = Math.floor(Date.now() / 1000);
return await this.PostgresClient.query(
'INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)',
[ key, data, (this.expire && !skipExpire) ? this.expire + now : null ]
)
.then(() => {
return true;
})
.catch(err => {
winston.error('failed to set postgres document', { key: key, error: err });
return false;
});
}
async get(key, skipExpire){
const now = Math.floor(Date.now() / 1000);
return await this.PostgresClient.query(
'SELECT id,value,expiration FROM entries WHERE key = $1 AND (expiration IS NULL OR expiration > $2)',
[ key, now ])
.then(async res => {
if (res.rows.length && this.expire && !skipExpire){
await this.PostgresClient.query(
'UPDATE entries SET expiration = $1 WHERE ID = $2',
[ this.expire + now, res.rows[0].id ]
);
}
return res.rows.length ? res.rows[0].value : null;
})
.catch(err => {
winston.error('error retrieving value from postgres', { error: err });
return null;
});
}
async safeConnect(){
return await this.PostgresClient.connect()
.then(() => {
winston.info('connected to postgres!');
return { error: null };
})
.catch(err => {
winston.error('failed connecting to postgres!', {error: err});
return { error: err };
});
}
}
module.exports = PostgresDocumentStore;