2014-06-09 18:48:35 +00:00
/*global require,module,process*/
var postgres = require ( 'pg' ) ;
var winston = require ( 'winston' ) ;
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 ;
2016-07-21 20:03:33 +00:00
this . secret = ( ) => Math . random ( ) . toString ( 24 ) . slice ( - 10 ) ;
2014-06-09 20:50:43 +00:00
} ;
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 ) ; }
2016-07-21 20:03:33 +00:00
var sc = that . secret ( ) ;
client . query ( 'INSERT INTO entries (key, value, expiration, secret) VALUES ($1, $2, $3, $4)' , [
2014-06-09 20:50:43 +00:00
key ,
data ,
2016-07-21 20:03:33 +00:00
that . expireJS && ! skipExpire ? that . expireJS + now : null ,
sc
2014-06-09 20:50:43 +00:00
] , function ( err , result ) {
if ( err ) {
winston . error ( 'error persisting value to postgres' , { error : err } ) ;
return callback ( false ) ;
}
2016-07-21 20:03:33 +00:00
callback ( true , sc ) ;
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
// 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
] , function ( err , result ) {
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
} ) ;
} ,
2016-07-21 20:03:33 +00:00
remove : function ( key , secret , callback ) {
var now = Math . floor ( new Date ( ) . getTime ( ) / 1000 ) ;
this . safeConnect ( function ( err , client , done ) {
if ( err ) { return callback ( false ) ; }
client . query ( 'SELECT id,value,expiration,secret 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 ) ;
}
if ( result . rows [ 0 ] . secret == secret ) {
client . query ( "DELETE FROM entries where KEY = $1" , [ key ] , function ( err , result ) {
if ( err ) {
winston . error ( 'error removing an item from postgres' , { error : err } ) ;
return callback ( false ) ;
}
else {
callback ( true ) ;
done ( ) ;
}
} ) ;
}
done ( ) ;
} ) ;
} ) ;
} ,
2014-06-09 18:48:35 +00:00
2014-06-09 20:50:43 +00:00
// 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 ) ;
}
} ) ;
}
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 ;