diff --git a/lib/client.js b/lib/client.js index 7c2cf1a3..9eb38699 100644 --- a/lib/client.js +++ b/lib/client.js @@ -16,8 +16,7 @@ var Client = function(config) { this.host = config.host; this.queryQueue = []; - this.stream = config.stream || new net.Stream(); - this.connection = new Connection({stream: this.stream}); + this.connection = config.connection || new Connection({stream: config.stream || new net.Stream()}); this.queryQueue = []; this.password = config.password || ''; this.lastBuffer = false; @@ -36,6 +35,7 @@ p.connect = function() { var con = this.connection; con.connect(this.port, this.host); + //once connection is established send startup message con.on('connect', function() { con.startup({ user: self.user, @@ -43,78 +43,102 @@ p.connect = function() { }); }); + //password request handling con.on('authenticationCleartextPassword', function() { con.password(self.password); }); + //password request handling con.on('authenticationMD5Password', function(msg) { var inner = Client.md5(self.password + self.user); var outer = Client.md5(inner + msg.salt.toString('binary')); var md5password = "md5" + outer; con.password(md5password); }); + + con.on('readyForQuery', function() { + self.readyForQuery = true; + + self.pulseQueryQueue(); + }); +}; + +p.pulseQueryQueue = function() { + if(this.readyForQuery===true && this.queryQueue.length > 0) { + this.readyForQuery = false; + var query = this.queryQueue.shift(); + if(typeof query === 'string') { + this.connection.query(query); + } + } +}; + +p.query = function(config) { + + this.queryQueue.push(config); + this.pulseQueryQueue(); }; Client.md5 = function(string) { return crypto.createHash('md5').update(string).digest('hex'); }; -var intParser = { - fromDbValue: parseInt -}; +// var intParser = { +// fromDbValue: parseInt +// }; -var floatParser = { - fromDbValue: parseFloat -}; +// var floatParser = { +// fromDbValue: parseFloat +// }; -var timeParser = { - fromDbValue: function(isoTime) { - var when = new Date(); - var split = isoTime.split(':'); - when.setHours(split[0]); - when.setMinutes(split[1]); - when.setSeconds(split[2].split('-') [0]); - return when; - } -}; +// var timeParser = { +// fromDbValue: function(isoTime) { +// var when = new Date(); +// var split = isoTime.split(':'); +// when.setHours(split[0]); +// when.setMinutes(split[1]); +// when.setSeconds(split[2].split('-') [0]); +// return when; +// } +// }; -var dateParser = { - fromDbValue: function(isoDate) { - return Date.parse(isoDate); - } -}; +// var dateParser = { +// fromDbValue: function(isoDate) { +// return Date.parse(isoDate); +// } +// }; -Client.dataTypes = { - 20: intParser, - 21: intParser, - 23: intParser, - 26: intParser, - 1700: floatParser, - 700: floatParser, - 701: floatParser, - 1083: timeParser, - 1266: timeParser, - 1114: dateParser, - 1184: dateParser -}; +// Client.dataTypes = { +// 20: intParser, +// 21: intParser, +// 23: intParser, +// 26: intParser, +// 1700: floatParser, +// 700: floatParser, +// 701: floatParser, +// 1083: timeParser, +// 1266: timeParser, +// 1114: dateParser, +// 1184: dateParser +// }; -p.processRowDescription = function(description) { - this.fields = description.fields; -}; +// p.processRowDescription = function(description) { +// this.fields = description.fields; +// }; -p.processDataRow = function(dataRow) { - var row = dataRow.fields; - var fields = this.fields || []; - var field, dataType; - for(var i = 0, len = row.length; i < len; i++) { - field = fields[i] || 0 - var dataType = Client.dataTypes[field.dataTypeID]; - if(dataType) { - row[i] = dataType.fromDbValue(row[i]); - } - } - this.emit('row',row); -}; +// p.processDataRow = function(dataRow) { +// var row = dataRow.fields; +// var fields = this.fields || []; +// var field, dataType; +// for(var i = 0, len = row.length; i < len; i++) { +// field = fields[i] || 0 +// var dataType = Client.dataTypes[field.dataTypeID]; +// if(dataType) { +// row[i] = dataType.fromDbValue(row[i]); +// } +// } +// this.emit('row',row); +// }; //end parsing methods module.exports = Client; diff --git a/test/unit/client/cleartext-password-tests.js b/test/unit/client/cleartext-password-tests.js index 0f147a75..ad77cdf1 100644 --- a/test/unit/client/cleartext-password-tests.js +++ b/test/unit/client/cleartext-password-tests.js @@ -4,11 +4,12 @@ test('cleartext password authentication', function(){ var client = createClient(); client.password = "!"; - client.stream.packets = []; + client.connection.stream.packets = []; client.connection.emit('authenticationCleartextPassword'); test('responds with password', function() { - assert.length(client.stream.packets, 1); - var packet = client.stream.packets[0]; + var packets = client.connection.stream.packets; + assert.length(packets, 1); + var packet = packets[0]; assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0]); }); diff --git a/test/unit/client/md5-password-tests.js b/test/unit/client/md5-password-tests.js index 649f06c2..d427f85b 100644 --- a/test/unit/client/md5-password-tests.js +++ b/test/unit/client/md5-password-tests.js @@ -6,13 +6,13 @@ test('md5 authentication', function() { client.connection.emit('authenticationMD5Password', {salt: salt}); test('responds', function() { - assert.length(client.stream.packets, 1); + assert.length(client.connection.stream.packets, 1); test('should have correct encrypted data', function() { var encrypted = Client.md5(client.password + client.user); encrypted = Client.md5(encrypted + salt.toString('binary')); var password = "md5" + encrypted //how do we want to test this? - assert.equalBuffers(client.stream.packets[0], new BufferList() + assert.equalBuffers(client.connection.stream.packets[0], new BufferList() .addCString(password).join(true,'p')) }); }); diff --git a/test/unit/client/simple-query-tests.js b/test/unit/client/simple-query-tests.js new file mode 100644 index 00000000..8970c838 --- /dev/null +++ b/test/unit/client/simple-query-tests.js @@ -0,0 +1,77 @@ +require(__dirname + "/test-helper"); + +var makeClient = function() { + var connection = new Connection({stream: "no"}); + connection.startup = function() {}; + connection.connect = function() {}; + connection.query = function(text) { + this.queries.push(text); + }; + connection.queries = []; + var client = new Client({connection: connection}); + client.connect(); + client.connection.emit('connect'); + return client; +}; + +test('executing query', function() { + + test("queing query", function() { + + test('when connection is ready', function() { + var client = makeClient(); + assert.empty(client.connection.queries); + client.connection.emit('readyForQuery'); + client.query('yes'); + assert.length(client.connection.queries, 1); + assert.equal(client.connection.queries, 'yes'); + }); + + test('when connection is not ready', function() { + var client = makeClient(); + + test('query is not sent', function() { + client.query('boom'); + assert.empty(client.connection.queries); + }); + + test('sends query to connection once ready', function() { + assert.ok(client.connection.emit('readyForQuery')); + assert.length(client.connection.queries, 1); + assert.equal(client.connection.queries[0], "boom"); + }); + + }); + test("multiple in the queue", function() { + var client = makeClient(); + var connection = client.connection; + var queries = connection.queries; + client.query('one'); + client.query('two'); + client.query('three'); + assert.empty(queries); + + test("after one ready for query",function() { + connection.emit('readyForQuery'); + assert.length(queries, 1); + assert.equal(queries[0], "one"); + }); + + test('after two ready for query', function() { + connection.emit('readyForQuery'); + assert.length(queries, 2); + }); + + test("after a bunch more", function() { + connection.emit('readyForQuery'); + connection.emit('readyForQuery'); + connection.emit('readyForQuery'); + assert.length(queries, 3); + assert.equal(queries[0], "one"); + assert.equal(queries[1], 'two'); + assert.equal(queries[2], 'three'); + }); + }); + }) +}); + diff --git a/test/unit/test-helper.js b/test/unit/test-helper.js index aca05a83..1fa907ce 100644 --- a/test/unit/test-helper.js +++ b/test/unit/test-helper.js @@ -16,7 +16,7 @@ createClient = function() { var stream = new MemoryStream(); stream.readyState = "open"; var client = new Client({ - stream: stream + connection: new Connection({stream: stream}) }); client.connect(); return client;