From 7e2f713af33bd38cb5edc4bbe79dfe51d68f31d6 Mon Sep 17 00:00:00 2001 From: brianc Date: Thu, 3 Mar 2011 18:21:43 +0000 Subject: [PATCH] running all client integration tests against native client - many failures --- lib/client-pool.js | 141 +++++++++++++++++++ lib/index.js | 138 +----------------- lib/native.js | 19 +-- test/integration/client/empty-query-tests.js | 5 +- test/integration/test-helper.js | 6 +- test/test-helper.js | 6 +- 6 files changed, 157 insertions(+), 158 deletions(-) create mode 100644 lib/client-pool.js diff --git a/lib/client-pool.js b/lib/client-pool.js new file mode 100644 index 00000000..39404a41 --- /dev/null +++ b/lib/client-pool.js @@ -0,0 +1,141 @@ +var Pool = require(__dirname + '/utils').Pool; +var defaults = require(__dirname + '/defaults'); + +module.exports = { + init: function(Client) { + + //wrap up common connection management boilerplate + var connect = function(config, callback) { + if(poolEnabled()) { + return getPooledClient(config, callback) + } + + var client = new Client(config); + client.connect(); + + var onError = function(error) { + client.removeListener('connect', onReady); + callback(error); + } + + var onReady = function() { + client.removeListener('error', onError); + callback(null, client); + client.on('drain', client.end.bind(client)); + } + + client.once('error', onError); + + //TODO refactor + //i don't like reaching into the client's connection for attaching + //to specific events here + client.once('connect', onReady); + } + + + //connection pool global cache + var clientPools = { + } + + var poolEnabled = function() { + return defaults.poolSize; + } + + var log = function() { + //do nothing + } + + //for testing + // var log = function() { + // console.log.apply(console, arguments); + // } + + var getPooledClient = function(config, callback) { + //lookup pool using config as key + //TODO this don't work so hot w/ object configs + var pool = clientPools[config]; + + //create pool if doesn't exist + if(!pool) { + //log("creating pool %s", config) + pool = clientPools[config] = new Pool(defaults.poolSize, function() { + //log("creating new client in pool %s", config) + var client = new Client(config); + client.connected = false; + return client; + }) + } + + pool.checkOut(function(err, client) { + + //if client already connected just + //pass it along to the callback and return + if(client.connected) { + callback(null, client); + return; + } + + var onError = function(error) { + client.removeListener('connect', onReady); + callback(error); + pool.checkIn(client); + } + + var onReady = function() { + client.removeListener('error', onError); + client.connected = true; + callback(null, client); + client.on('drain', function() { + pool.checkIn(client); + }); + } + + client.once('error', onError); + + //TODO refactor + //i don't like reaching into the client's connection for attaching + //to specific events here + client.once('connect', onReady); + + client.connect(); + + }); + } + + //destroys the world + //or optionally only a single pool + //mostly used for testing or + //a hard shutdown + var end = function(name) { + if(!name) { + for(var poolName in clientPools) { + end(poolName) + return + } + } + var pool = clientPools[name]; + //log("destroying pool %s", name); + pool.waits.forEach(function(wait) { + wait(new Error("Client is being destroyed")) + }) + pool.waits = []; + pool.items.forEach(function(item) { + var client = item.ref; + if(client.activeQuery) { + //log("client is still active, waiting for it to complete"); + client.on('drain', client.end.bind(client)) + } else { + client.end(); + } + }) + //remove reference to pool lookup + clientPools[name] = null; + delete(clientPools[name]) + }; + //export functions with closures to client constructor + return { + connect: connect, + end: end + } + } +}; diff --git a/lib/index.js b/lib/index.js index 22498d0b..21ed6d2e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,142 +1,12 @@ var EventEmitter = require('events').EventEmitter; -var Pool = require(__dirname + '/utils').Pool; + var Client = require(__dirname+'/client'); var defaults = require(__dirname + '/defaults'); - -//wrap up common connection management boilerplate -var connect = function(config, callback) { - if(poolEnabled()) { - return getPooledClient(config, callback) - } - - var client = new Client(config); - client.connect(); - - var onError = function(error) { - client.removeListener('connect', onReady); - callback(error); - } - - var onReady = function() { - client.removeListener('error', onError); - callback(null, client); - client.on('drain', client.end.bind(client)); - } - - client.once('error', onError); - - //TODO refactor - //i don't like reaching into the client's connection for attaching - //to specific events here - client.once('connect', onReady); -} - - -//connection pool global cache -var clientPools = { -} - -var poolEnabled = function() { - return defaults.poolSize; -} - -var log = function() { - //do nothing -} - -//for testing -// var log = function() { -// console.log.apply(console, arguments); -// } - -var getPooledClient = function(config, callback) { - //lookup pool using config as key - //TODO this don't work so hot w/ object configs - var pool = clientPools[config]; - - //create pool if doesn't exist - if(!pool) { - //log("creating pool %s", config) - pool = clientPools[config] = new Pool(defaults.poolSize, function() { - //log("creating new client in pool %s", config) - var client = new Client(config); - client.connected = false; - return client; - }) - } - - pool.checkOut(function(err, client) { - - //if client already connected just - //pass it along to the callback and return - if(client.connected) { - callback(null, client); - return; - } - - var onError = function(error) { - client.connection.removeListener('readyForQuery', onReady); - callback(error); - pool.checkIn(client); - } - - var onReady = function() { - client.removeListener('error', onError); - client.connected = true; - callback(null, client); - client.on('drain', function() { - pool.checkIn(client); - }); - } - - client.once('error', onError); - - //TODO refactor - //i don't like reaching into the client's connection for attaching - //to specific events here - client.connection.once('readyForQuery', onReady); - - client.connect(); - - }); -} - -//destroys the world -//or optionally only a single pool -//mostly used for testing or -//a hard shutdown -var end = function(name) { - if(!name) { - for(var poolName in clientPools) { - end(poolName) - return - } - } - var pool = clientPools[name]; - //log("destroying pool %s", name); - pool.waits.forEach(function(wait) { - wait(new Error("Client is being destroyed")) - }) - pool.waits = []; - pool.items.forEach(function(item) { - var client = item.ref; - if(client.activeQuery) { - //log("client is still active, waiting for it to complete"); - client.on('drain', client.end.bind(client)) - } else { - client.end(); - } - }) - //remove reference to pool lookup - clientPools[name] = null; - delete(clientPools[name]) -} - - +var pool = require(__dirname + "/client-pool").init(Client); module.exports = { Client: Client, Connection: require(__dirname + '/connection'), - connect: connect, - end: end, + connect: pool.connect, + end: pool.end, defaults: defaults } diff --git a/lib/native.js b/lib/native.js index 62906f2e..63f1edba 100644 --- a/lib/native.js +++ b/lib/native.js @@ -105,17 +105,6 @@ var ctor = function(config) { return connection; }; -var connect = function(config, callback) { - var client = new ctor(config); - client.connect(); - client.on('connect', function() { - callback(null, client); - }) - client.on('error', function(err) { - callback(err, null); - }) -}; - //event emitter proxy var NativeQuery = function(text, values, callback) { if(typeof text == 'object') { @@ -184,10 +173,10 @@ p._translateValues = function() { } } +var pool = require(__dirname + '/client-pool').init(ctor); + module.exports = { Client: ctor, - connect: connect, - end: function() { - - } + connect: pool.connect, + end: pool.end }; diff --git a/test/integration/client/empty-query-tests.js b/test/integration/client/empty-query-tests.js index ce9f9738..721da42d 100644 --- a/test/integration/client/empty-query-tests.js +++ b/test/integration/client/empty-query-tests.js @@ -3,6 +3,7 @@ var client = helper.client(); test("empty query message handling", function() { client.query(""); - assert.emits(client.connection, 'emptyQuery'); - client.on('drain', client.end.bind(client)); + assert.emits(client, 'drain', function() { + client.end.bind(client); + }) }); diff --git a/test/integration/test-helper.js b/test/integration/test-helper.js index 510a5855..d02fd178 100644 --- a/test/integration/test-helper.js +++ b/test/integration/test-helper.js @@ -1,6 +1,8 @@ var helper = require(__dirname + '/../test-helper'); + +if(helper.args.native) { + Client = require(__dirname + '/../../lib/native').Client; +} //export parent helper stuffs module.exports = helper; -if(helper.args.verbose) { -} diff --git a/test/test-helper.js b/test/test-helper.js index e554dbdf..37ff47dd 100644 --- a/test/test-helper.js +++ b/test/test-helper.js @@ -9,11 +9,7 @@ var BufferList = require(__dirname+'/buffer-list') var Connection = require('connection'); var args = require(__dirname + '/cli'); -if(args.libpq) { -Client = require('binding').Client; -} else { -Client = require('client'); -} +Client = require(__dirname + '/../lib').Client; process.on('uncaughtException', function(d) { if ('stack' in d && 'message' in d) {