|
|
|
@ -3,72 +3,78 @@ |
|
|
|
|
var postgres = require('pg'); |
|
|
|
|
var winston = require('winston'); |
|
|
|
|
|
|
|
|
|
(function () { |
|
|
|
|
// create table entries (id SERIAL primary key, key varchar(255) not null, value text not null, expiration int);
|
|
|
|
|
// CREATE UNIQUE INDEX unique_key ON entries (key);
|
|
|
|
|
|
|
|
|
|
'use strict'; |
|
|
|
|
// A postgres document store
|
|
|
|
|
var PostgresDocumentStore = function (options) { |
|
|
|
|
this.expireJS = options.expire; |
|
|
|
|
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// A postgres document store
|
|
|
|
|
var PostgresDocumentStore = function (options) { |
|
|
|
|
this.expireJS = options.expire * 1000; |
|
|
|
|
this.connectionString = process.env.DATABASE_URL; |
|
|
|
|
}; |
|
|
|
|
PostgresDocumentStore.prototype = { |
|
|
|
|
|
|
|
|
|
PostgresDocumentStore.prototype = { |
|
|
|
|
|
|
|
|
|
// Set a given key
|
|
|
|
|
set: function (key, data, callback, skipExpire) { |
|
|
|
|
var now = 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 ? now + that.expireJS : null |
|
|
|
|
], function (err, result) { |
|
|
|
|
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) { |
|
|
|
|
var now = new Date().getTime() / 1000; |
|
|
|
|
var that = this; |
|
|
|
|
this.safeConnect(function (err, client, done) { |
|
|
|
|
if (err) { return callback(false); } |
|
|
|
|
client.query('SELECT value from entries where KEY = $1 AND (expiration IS NULL or expiration < $2)', [ |
|
|
|
|
key, |
|
|
|
|
that.expireJS ? now - that.expireJS : 0 |
|
|
|
|
], 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); |
|
|
|
|
}); |
|
|
|
|
// 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 |
|
|
|
|
], function (err, result) { |
|
|
|
|
if (err) { |
|
|
|
|
winston.error('error persisting value to postgres', { error: err }); |
|
|
|
|
return callback(false); |
|
|
|
|
} |
|
|
|
|
callback(true); |
|
|
|
|
done(); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
// A connection wrapper
|
|
|
|
|
safeConnect: function (callback) { |
|
|
|
|
postgres.connect(this.connectionString, function (err, client, done) { |
|
|
|
|
// 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) { |
|
|
|
|
if (err) { |
|
|
|
|
winston.error('error connecting to postgres', { error: err }); |
|
|
|
|
callback(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, result) { |
|
|
|
|
if (!err) { |
|
|
|
|
done(); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} else { |
|
|
|
|
callback(undefined, client, done); |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
module.export = PostgresDocumentStore; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
}()); |
|
|
|
|
module.exports = PostgresDocumentStore; |
|
|
|
|