2011-06-13 11:23:02 +08:00
var _ = require ( 'underscore' )
2011-09-07 23:50:35 +08:00
, Step = require ( 'step' )
2011-09-07 23:58:53 +08:00
, pg = require ( 'pg' ) ; //.native; // disabled for now due to: https://github.com/brianc/node-postgres/issues/48
2011-09-07 23:50:35 +08:00
_ . mixin ( require ( 'underscore.string' ) ) ;
2011-06-13 11:23:02 +08:00
// PSQL
//
// A simple postgres wrapper with logic about username and database to connect
//
// * intended for use with pg_bouncer
// * defaults to connecting with a "READ ONLY" user to given DB if not passed a specific user_id
2011-08-22 20:33:12 +08:00
var PSQL = function ( user _id , db , limit , offset ) {
2011-08-25 18:15:52 +08:00
var error _text = "Incorrect access parameters. If you are accessing via OAuth, please check your tokens are correct. For public users, please ensure your table is published."
2011-08-22 20:33:12 +08:00
if ( ! _ . isString ( user _id ) && ! _ . isString ( db ) ) throw new Error ( error _text ) ;
2011-06-13 11:23:02 +08:00
var me = {
public _user : "publicuser"
, user _id : user _id
, db : db
2011-07-06 00:31:01 +08:00
, limit : limit
, offset : offset
2011-06-13 11:23:02 +08:00
, client : null
2011-09-16 19:43:10 +08:00
} ;
2011-06-13 11:23:02 +08:00
me . username = function ( ) {
2011-09-16 19:43:10 +08:00
var username = this . public _user ;
if ( _ . isString ( this . user _id ) )
2011-06-13 11:23:02 +08:00
username = _ . template ( global . settings . db _user , { user _id : this . user _id } ) ;
2011-09-16 19:43:10 +08:00
return username ;
2011-09-07 23:50:35 +08:00
} ;
2011-09-16 19:43:10 +08:00
me . database = function ( ) {
var database = db ;
2011-06-13 11:23:02 +08:00
if ( _ . isString ( this . user _id ) )
database = _ . template ( global . settings . db _base _name , { user _id : this . user _id } ) ;
2011-09-16 19:43:10 +08:00
2011-06-13 11:23:02 +08:00
return database ;
2011-09-07 23:50:35 +08:00
} ;
2011-09-16 19:43:10 +08:00
2011-06-13 11:23:02 +08:00
// memoizes connection in object. move to proper pool.
me . connect = function ( callback ) {
var that = this
2011-06-17 00:23:38 +08:00
var conString = "tcp://" + this . username ( ) + "@" + global . settings . db _host + ":" + global . settings . db _port + "/" + this . database ( ) ;
2011-09-16 19:43:10 +08:00
2011-06-13 11:23:02 +08:00
if ( that . client ) {
return callback ( null , that . client ) ;
} else {
pg . connect ( conString , function ( err , client ) {
that . client = client ;
2011-09-16 19:43:10 +08:00
return callback ( err , client ) ;
} ) ;
2011-06-13 11:23:02 +08:00
}
2011-09-07 23:50:35 +08:00
} ;
2011-09-16 19:43:10 +08:00
2011-06-13 11:23:02 +08:00
me . query = function ( sql , callback ) {
2011-07-06 00:31:01 +08:00
var that = this ;
2011-09-07 23:50:35 +08:00
Step (
function ( ) {
that . connect ( this ) ;
} ,
function ( err , client ) {
if ( err ) return callback ( err , null ) ;
client . query ( that . window _sql ( sql ) , this ) ;
} ,
function ( err , res ) {
//if (err) console.log(err);
callback ( err , res )
}
) ;
2011-09-16 19:43:10 +08:00
} ;
2011-06-16 17:55:36 +08:00
2011-06-13 11:23:02 +08:00
me . end = function ( ) {
2011-06-16 17:55:36 +08:00
this . client . end ( ) ;
2011-09-07 23:50:35 +08:00
} ;
2011-09-16 19:43:10 +08:00
2011-07-06 00:31:01 +08:00
// little hack for UI
me . window _sql = function ( sql ) {
2011-08-05 20:35:32 +08:00
// only window select functions
2011-08-05 21:15:08 +08:00
if ( _ . isNumber ( this . limit ) && _ . isNumber ( this . offset ) && /^\s*SELECT.*$/ . test ( sql . toUpperCase ( ) ) ) {
2011-07-06 00:31:01 +08:00
return "SELECT * FROM (" + sql + ") AS cdbq_1 LIMIT " + this . limit + " OFFSET " + this . offset ;
} else {
return sql ;
2011-09-16 19:43:10 +08:00
}
2011-09-07 23:50:35 +08:00
} ;
2011-09-16 19:43:10 +08:00
2011-11-22 07:06:38 +08:00
// throw exception if system table detected
2011-06-13 11:23:02 +08:00
return me ;
} ;
2011-06-13 18:31:50 +08:00
module . exports = PSQL ;