diff --git a/lib/native.js b/lib/native.js index 867ac646..ca88701a 100644 --- a/lib/native.js +++ b/lib/native.js @@ -12,7 +12,8 @@ var nativeConnect = p.connect; p.connect = function() { var self = this; - getLibpgConString(this._config, function(conString) { + utils.buildLibpqConnectionString(this._config, function(err, conString) { + if(err) return self.emit('error', err); nativeConnect.call(self, conString); }) } @@ -121,7 +122,7 @@ var NativeQuery = function(text, values, callback) { if(item instanceof Date) { this.values[i] = JSON.stringify(item); } else { - this.values[i] = item.toString(); + this.values[i] = item.toString(); } } } @@ -167,40 +168,11 @@ p.handleReadyForQuery = function() { this.emit('end'); }; -var add = function(params, config, paramName) { - var value = config[paramName]; - if(value) { - params.push(paramName+"='"+value+"'"); - } -} - -//connection string helper -var getLibpgConString = function(config, callback) { - if(typeof config == 'object') { - var params = [] - add(params, config, 'user'); - add(params, config, 'password'); - add(params, config, 'port'); - if(config.database) { - params.push("dbname='" + config.database + "'"); - } - if(config.host) { - if(config.host != 'localhost' && config.host != '127.0.0.1') { - throw new Error("Need to use node to do async DNS on host"); - } - params.push("hostaddr=127.0.0.1 "); - } - callback(params.join(" ")); - } else { - throw new Error("Unrecognized config type for connection"); - } -} - var pool = require(__dirname + '/client-pool').init(ctor); module.exports = { Client: ctor, connect: pool.connect, end: pool.end, - defaults: require(__dirname + '/defaults') + defaults: require(__dirname + '/defaults') }; diff --git a/lib/utils.js b/lib/utils.js index f8c2e12f..80483307 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -116,7 +116,49 @@ var normalizeConnectionInfo = function(config) { } }; + +var add = function(params, config, paramName) { + var value = config[paramName]; + if(value) { + params.push(paramName+"='"+value+"'"); + } +} + +//builds libpq specific connection string +//from a supplied config object +//the config object conforms to the interface of the config object +//accepted by the pure javascript client +var getLibpgConString = function(config, callback) { + if(typeof config == 'object') { + var params = [] + add(params, config, 'user'); + add(params, config, 'password'); + add(params, config, 'port'); + if(config.database) { + params.push("dbname='" + config.database + "'"); + } + if(config.host) { + if(config.host != 'localhost' && config.host != '127.0.0.1') { + //do dns lookup + return require('dns').lookup(config.host, 4, function(err, address) { + if(err) return callback(err, null); + params.push("hostaddr="+address) + callback(null, params.join(" ")) + }) + } + params.push("hostaddr=127.0.0.1 "); + } + callback(null, params.join(" ")); + } else { + throw new Error("Unrecognized config type for connection"); + } +} + module.exports = { Pool: Pool, - normalizeConnectionInfo: normalizeConnectionInfo + normalizeConnectionInfo: normalizeConnectionInfo, + //only exported here to make testing of this method possible + //since it contains quite a bit of logic and testing for + //each connection scenario in an integration test is impractical + buildLibpqConnectionString: getLibpgConString } diff --git a/test/integration/client/error-handling-tests.js b/test/integration/client/error-handling-tests.js index b5871c82..52f4e9e1 100644 --- a/test/integration/client/error-handling-tests.js +++ b/test/integration/client/error-handling-tests.js @@ -85,3 +85,13 @@ test('error handling', function(){ }); }); + +test('when connecting to invalid host', function() { + var client = new Client({ + user: 'brian', + password: '1234', + host: 'asldkfjasdf!!#1308140.com' + }) + assert.emits(client, 'error'); + client.connect(); +}) diff --git a/test/unit/utils-tests.js b/test/unit/utils-tests.js index cdf3f557..da557b55 100644 --- a/test/unit/utils-tests.js +++ b/test/unit/utils-tests.js @@ -187,3 +187,56 @@ test('normalizing connection info', function() { }) }) }) + +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' + } + utils.buildLibpqConnectionString(config, 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: 'example.com' + } + utils.buildLibpqConnectionString(config, assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'") + checkForPart(parts, "hostaddr=192.0.32.10") + })) + }) + + test('error when dns fails', function() { + var config = { + user: 'brian', + password: 'asf', + port: 5432, + host: 'asdlfkjasldfkksfd#!$!!!!..com' + } + utils.buildLibpqConnectionString(config, assert.calls(function(err, constring) { + assert.ok(err); + assert.isNull(constring) + })) + }) + +})