diff --git a/lib/connection-parameters.js b/lib/connection-parameters.js index e006e58e..c2c5a8df 100644 --- a/lib/connection-parameters.js +++ b/lib/connection-parameters.js @@ -1,3 +1,5 @@ +var dns = require('dns'); + var defaults = require(__dirname + '/defaults'); var val = function(key, config) { @@ -33,6 +35,33 @@ var ConnectionParameters = function(config) { this.password = val('password', config); this.binary = val('binary', config); this.ssl = config.ssl || defaults.ssl; + this.isDomainSocket = (!(this.host||'').indexOf('/')); +}; + +var add = function(params, config, paramName) { + var value = config[paramName]; + if(value) { + params.push(paramName+"='"+value+"'"); + } +}; + +ConnectionParameters.prototype.getLibpqConnectionString = function(cb) { + var params = [] + add(params, this, 'user'); + add(params, this, 'password'); + add(params, this, 'port'); + if(this.database) { + params.push("dbname='" + this.database + "'"); + } + if(this.isDomainSocket) { + params.push("host=" + this.host); + return cb(null, params.join(' ')); + } + dns.lookup(this.host, function(err, address) { + if(err) return cb(err, null); + params.push("hostaddr=" + address); + return cb(null, params.join(' ')); + }); }; module.exports = ConnectionParameters; diff --git a/test/unit/connection-parameters/creation-tests.js b/test/unit/connection-parameters/creation-tests.js index e8306b64..b4707c9a 100644 --- a/test/unit/connection-parameters/creation-tests.js +++ b/test/unit/connection-parameters/creation-tests.js @@ -26,6 +26,7 @@ var compare = function(actual, expected, type) { test('ConnectionParameters initializing from defaults', function() { var subject = new ConnectionParameters(); compare(subject, defaults, 'defaults'); + assert.ok(subject.isDomainSocket === false); }); test('ConnectionParameters initializing from config', function() { @@ -43,4 +44,98 @@ test('ConnectionParameters initializing from config', function() { }; var subject = new ConnectionParameters(config); compare(subject, config, 'config'); + assert.ok(subject.isDomainSocket === false); }); + +test('initializing with unix domain socket', function() { + var subject = new ConnectionParameters('/var/run/pg.sock'); + assert.ok(subject.isDomainSocket); + assert.equal(subject.host, '/var/run/pg.sock'); +}); + +test('libpq connection string building', function() { + var checkForPart = function(array, part) { + assert.ok(array.indexOf(part) > -1, array.join(" ") + " did not contain " + part); + } + + test('builds simple string', function() { + var config = { + user: 'brian', + password: 'xyz', + port: 888, + host: 'localhost', + database: 'bam' + } + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "password='xyz'"); + checkForPart(parts, "port='888'"); + checkForPart(parts, "hostaddr=127.0.0.1"); + checkForPart(parts, "dbname='bam'"); + })); + }); + + test('builds dns string', function() { + var config = { + user: 'brian', + password: 'asdf', + port: 5432, + host: 'localhost' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "hostaddr=127.0.0.1"); + })); + }); + + test('error when dns fails', function() { + var config = { + user: 'brian', + password: 'asf', + port: 5432, + host: 'asdlfkjasldfkksfd#!$!!!!..com' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.ok(err); + assert.isNull(constring) + })); + }); + + test('connecting to unix domain socket', function() { + var config = { + user: 'brian', + password: 'asf', + port: 5432, + host: '/var/run/pgsockbla' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "host=/var/run/pgsockbla"); + })); + }); + + test('password contains < and/or > characters', function () { + return false; + var sourceConfig = { + user:'brian', + password: 'helloe', + port: 5432, + host: 'localhost', + database: 'postgres' + } + var connectionString = 'pg://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = new ConnectionParameters(connectionString); + assert.equal(subject.password, sourceConfig.password); + }); + +})