diff --git a/lib/client.js b/lib/client.js index 3af94fe0..6efcb027 100644 --- a/lib/client.js +++ b/lib/client.js @@ -10,7 +10,7 @@ var Connection = require(__dirname + '/connection'); var Client = function(config) { EventEmitter.call(this); if(typeof config === 'string') { - config = utils.parseConnectionString(config) + config = utils.normalizeConnectionInfo(config) } config = config || {}; this.user = config.user || defaults.user; @@ -31,7 +31,12 @@ var p = Client.prototype; p.connect = function() { var self = this; var con = this.connection; - con.connect(this.port, this.host); + if(this.host && this.host.indexOf('/') === 0) { + con.connect(this.host + '/.s.PGSQL.' + this.port); + } else { + con.connect(this.port, this.host); + } + //once connection is established send startup message con.on('connect', function() { diff --git a/lib/index.js b/lib/index.js index 4fe24fe5..eed23da0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,9 +1,9 @@ var EventEmitter = require('events').EventEmitter; var sys = require('sys'); var net = require('net'); -var Pool = require(__dirname + '/utils').Pool; var Client = require(__dirname+'/client'); var defaults = require(__dirname + '/defaults'); +var Pool = require(__dirname + '/utils').Pool; //wrap up common connection management boilerplate var connect = function(config, callback) { diff --git a/lib/utils.js b/lib/utils.js index 32726b8f..ecc84239 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,5 @@ var url = require('url'); +var defaults = require(__dirname + "/defaults"); var events = require('events'); var sys = require('sys'); @@ -73,17 +74,49 @@ p._pulse = function(item, cb) { return true; } return false; -} +}; + +var parseConnectionString = function(str) { + //unix socket + if(str.charAt(0) === '/') { + return { host: str }; + } + var result = url.parse(str); + var config = {}; + config.host = result.hostname; + config.database = result.pathname ? result.pathname.slice(1) : null + var auth = (result.auth || ':').split(':'); + config.user = auth[0]; + config.password = auth[1]; + config.port = result.port; + return config; +}; + +//allows passing false as property to remove it from config +var norm = function(config, propName) { + config[propName] = (config[propName] || (config[propName] === false ? undefined : defaults[propName])) +}; + +//normalizes connection info +//which can be in the form of an object +//or a connection string +var normalizeConnectionInfo = function(config) { + switch(typeof config) { + case 'object': + norm(config, 'user'); + norm(config, 'password'); + norm(config, 'host'); + norm(config, 'port'); + norm(config, 'database'); + return config; + case 'string': + return normalizeConnectionInfo(parseConnectionString(config)); + default: + throw new Error("Unrecognized connection config parameter: " + config); + } +}; module.exports = { Pool: Pool, - parseConnectionString: function(str) { - var result = url.parse(str); - result.host = result.hostname; - result.database = result.pathname ? result.pathname.slice(1) : null - var auth = (result.auth || ':').split(':'); - result.user = auth[0]; - result.password = auth[1]; - return result; - } + normalizeConnectionInfo: normalizeConnectionInfo } diff --git a/test/unit/client/configuration-tests.js b/test/unit/client/configuration-tests.js index 8521301d..cb60119b 100644 --- a/test/unit/client/configuration-tests.js +++ b/test/unit/client/configuration-tests.js @@ -50,3 +50,17 @@ test('initializing from a config string', function() { }) + +test('calls connect correctly on connection', function() { + var client = new Client("/tmp"); + var usedPort = ""; + var usedHost = ""; + client.connection.connect = function(port, host) { + usedPort = port; + usedHost = host; + }; + client.connect(); + assert.equal(usedPort, "/tmp/.s.PGSQL.5432"); + assert.strictEqual(usedHost, undefined) +}) + diff --git a/test/unit/utils-tests.js b/test/unit/utils-tests.js index 1fa733c9..428ef406 100644 --- a/test/unit/utils-tests.js +++ b/test/unit/utils-tests.js @@ -1,5 +1,7 @@ require(__dirname + '/test-helper'); -var Pool = require(__dirname + "/../../lib/utils").Pool; +var utils = require(__dirname + "/../../lib/utils"); +var Pool = utils.Pool; +var defaults = require(__dirname + "/../../lib").defaults; //this tests the monkey patching //to ensure comptability with older @@ -109,8 +111,75 @@ test('when creating async new pool members', function() { })) })) }) - }) +test('normalizing connection info', function() { + test('with objects', function() { + test('empty object uses defaults', function() { + var input = {}; + var output = utils.normalizeConnectionInfo(input); + assert.equal(output.user, defaults.user); + assert.equal(output.database, defaults.database); + assert.equal(output.port, defaults.port); + assert.equal(output.host, defaults.host); + assert.equal(output.password, defaults.password); + }); + test('full object ignores defaults', function() { + var input = { + user: 'test1', + database: 'test2', + port: 'test3', + host: 'test4', + password: 'test5' + }; + assert.equal(utils.normalizeConnectionInfo(input), input); + }); + test('connection string', function() { + test('non-unix socket', function() { + test('uses defaults', function() { + var input = ""; + var output = utils.normalizeConnectionInfo(input); + assert.equal(output.user, defaults.user); + assert.equal(output.database, defaults.database); + assert.equal(output.port, defaults.port); + assert.equal(output.host, defaults.host); + assert.equal(output.password, defaults.password); + }); + test('ignores defaults if string contains them all', function() { + var input = "tcp://user1:pass2@host3:3333/databaseName"; + var output = utils.normalizeConnectionInfo(input); + assert.equal(output.user, 'user1'); + assert.equal(output.database, 'databaseName'); + assert.equal(output.port, 3333); + assert.equal(output.host, 'host3'); + assert.equal(output.password, 'pass2'); + }) + }); + + test('unix socket', function() { + test('uses defaults', function() { + var input = "/var/run/postgresql"; + var output = utils.normalizeConnectionInfo(input); + assert.equal(output.user, process.env.USER); + assert.equal(output.host, '/var/run/postgresql'); + assert.equal(output.database, process.env.USER); + assert.equal(output.port, 5432); + }); + + test('uses overridden defaults', function() { + defaults.host = "/var/run/postgresql"; + defaults.user = "boom"; + defaults.password = "yeah"; + defaults.port = 1234; + var output = utils.normalizeConnectionInfo("asdf"); + assert.equal(output.user, "boom"); + assert.equal(output.password, "yeah"); + assert.equal(output.port, 1234); + assert.equal(output.host, "/var/run/postgresql"); + }) + }) + }) + }) +})