support for connecting via domain socket

This commit is contained in:
bmc 2011-03-01 20:35:14 +00:00
parent 9eed57be84
commit c0ef5296c6
5 changed files with 136 additions and 15 deletions

View File

@ -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() {

View File

@ -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) {

View File

@ -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
}

View File

@ -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)
})

View File

@ -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");
})
})
})
})
})