mirror of
https://github.com/brianc/node-postgres.git
synced 2026-01-18 15:55:05 +00:00
simple bound queries
This commit is contained in:
parent
5650b02993
commit
057df36e2a
@ -147,6 +147,18 @@ p.bind = function(config) {
|
||||
this.send('B', buffer.join());
|
||||
};
|
||||
|
||||
p.execute = function(name, rows) {
|
||||
this.send('E',new BufferList().addCString(name||'').addInt32(rows||0).join());
|
||||
};
|
||||
|
||||
p.flush = function() {
|
||||
this.send('H',Buffer(0));
|
||||
}
|
||||
|
||||
p.sync = function() {
|
||||
this.send('S', Buffer(0));
|
||||
};
|
||||
|
||||
p.pulseQueryQueue = function(ready) {
|
||||
if(!this.readyForQuery) {
|
||||
return;
|
||||
@ -255,11 +267,13 @@ var messageNames = {
|
||||
Z: 'readyForQuery',
|
||||
T: 'rowDescription',
|
||||
D: 'dataRow',
|
||||
E: 'error'
|
||||
E: 'error',
|
||||
1: 'parseComplete',
|
||||
2: 'bindComplete'
|
||||
};
|
||||
|
||||
p.parseMessage = function() {
|
||||
var remaining = this.buffer.length - this.offset - 1;
|
||||
var remaining = this.buffer.length - (this.offset);
|
||||
if(remaining < 5) {
|
||||
//cannot read id + length without at least 5 bytes
|
||||
//just abort the read now
|
||||
@ -276,7 +290,7 @@ p.parseMessage = function() {
|
||||
length: this.parseInt32()
|
||||
};
|
||||
|
||||
if(remaining < message.length) {
|
||||
if(remaining <= message.length) {
|
||||
this.lastBuffer = this.buffer;
|
||||
//rewind the last 5 bytes we read
|
||||
this.lastOffset = this.offset-5;
|
||||
@ -365,6 +379,7 @@ p.parseD = function(msg) {
|
||||
return msg;
|
||||
};
|
||||
|
||||
//parses error
|
||||
p.parseE = function(msg) {
|
||||
var fields = {};
|
||||
var fieldType = this.readString(1);
|
||||
@ -387,6 +402,16 @@ p.parseE = function(msg) {
|
||||
return msg;
|
||||
};
|
||||
|
||||
//parses parseComplete
|
||||
p.parse1 = function(msg) {
|
||||
return msg;
|
||||
};
|
||||
|
||||
//parses bindComplete
|
||||
p.parse2 = function(msg) {
|
||||
return msg;
|
||||
};
|
||||
|
||||
p.readChar = function() {
|
||||
return Buffer([this.buffer[this.offset++]]).toString(this.encoding);
|
||||
};
|
||||
|
||||
34
test/integration/simple-bound-query-tests.js
Normal file
34
test/integration/simple-bound-query-tests.js
Normal file
@ -0,0 +1,34 @@
|
||||
var helper = require(__dirname + '/test-helper');
|
||||
http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
|
||||
|
||||
helper.connect(function(con) {
|
||||
|
||||
con.parse({
|
||||
text: 'select * from ids'
|
||||
});
|
||||
con.flush();
|
||||
|
||||
con.once('parseComplete', function() {
|
||||
con.bind();
|
||||
con.flush();
|
||||
});
|
||||
|
||||
con.once('bindComplete', function() {
|
||||
con.execute();
|
||||
con.flush();
|
||||
});
|
||||
|
||||
con.on('dataRow', function(msg) {
|
||||
sys.debug("got row from pepared query");
|
||||
});
|
||||
|
||||
con.on('commandComplete', function() {
|
||||
con.sync();
|
||||
});
|
||||
|
||||
con.on('readyForQuery', function() {
|
||||
con.end();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -1,27 +1,24 @@
|
||||
var helper = require(__dirname+"/test-helper");
|
||||
var assert = require('assert');
|
||||
var client = helper.client();
|
||||
|
||||
var rows = [];
|
||||
//testing the low level 1-1 mapping api of client to postgres messages
|
||||
//it's cumbersome to use the api this way
|
||||
client.query('create temporary table bang(id integer)');
|
||||
client.once('commandComplete', function() {
|
||||
client.query('insert into bang(id) values(1)');
|
||||
client.once('commandComplete', function() {
|
||||
client.query('select * from bang');
|
||||
client.on('dataRow', function(row) {
|
||||
rows.push(row.fields);
|
||||
});
|
||||
client.on('readyForQuery',function() {
|
||||
client.end();
|
||||
});
|
||||
helper.connect(function(con) {
|
||||
con.query('select * from ids');
|
||||
con.on('dataRow', function(msg) {
|
||||
rows.push(msg.fields);
|
||||
});
|
||||
con.once('readyForQuery', function() {
|
||||
con.end();
|
||||
});
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.equal(rows.length, 1);
|
||||
assert.equal(rows.length, 2);
|
||||
assert.equal(rows[0].length, 1);
|
||||
assert.equal(rows[0], 1);
|
||||
assert.equal(rows[0] [0], 1);
|
||||
assert.equal(rows[1] [0], 2);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -2,15 +2,23 @@ Client = require(__dirname+'/../../lib/client');
|
||||
sys = require('sys');
|
||||
|
||||
//creates a configured, connecting client
|
||||
var client = function() {
|
||||
var client = new Client({
|
||||
var connect = function(onReady) {
|
||||
var con = new Client({
|
||||
database: 'postgres',
|
||||
user: 'brian'
|
||||
});
|
||||
client.connect();
|
||||
return client;
|
||||
con.connect();
|
||||
con.once('readyForQuery', function() {
|
||||
con.query('create temporary table ids(id integer)');
|
||||
con.once('readyForQuery', function() {
|
||||
con.query('insert into ids(id) values(1); insert into ids(id) values(2);');
|
||||
con.once('readyForQuery',function() {
|
||||
onReady(con);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
client: client
|
||||
connect: connect
|
||||
};
|
||||
|
||||
@ -9,7 +9,8 @@ var paramStatusBuffer = buffers.parameterStatus('client_encoding', 'UTF8');
|
||||
var readyForQueryBuffer = buffers.readyForQuery();
|
||||
var backendKeyDataBuffer = buffers.backendKeyData(1,2);
|
||||
var commandCompleteBuffer = buffers.commandComplete("SELECT 3");
|
||||
|
||||
var parseCompleteBuffer = buffers.parseComplete();
|
||||
var bindCompleteBuffer = buffers.bindComplete();
|
||||
|
||||
var addRow = function(bufferList, name, offset) {
|
||||
return bufferList.addCString(name) //field name
|
||||
@ -294,6 +295,20 @@ test('Client', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('parses parse complete command', function() {
|
||||
testForMessage(parseCompleteBuffer, {
|
||||
id: '1',
|
||||
name: 'parseComplete'
|
||||
});
|
||||
});
|
||||
|
||||
test('parses bind complete command', function() {
|
||||
testForMessage(bindCompleteBuffer, {
|
||||
id: '2',
|
||||
name: 'bindComplete'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//since the data message on a stream can randomly divide the incomming
|
||||
|
||||
@ -40,9 +40,9 @@ test('prepared queries', function() {
|
||||
//server raises parse complete message
|
||||
|
||||
test('sends bind message', function() {
|
||||
|
||||
|
||||
test('binding to unnamed prepared statement with no values', function() {
|
||||
|
||||
|
||||
client.bind();
|
||||
assert.length(client.stream.packets, 1);
|
||||
var packet = client.stream.packets.pop();
|
||||
@ -57,8 +57,35 @@ test('prepared queries', function() {
|
||||
|
||||
});
|
||||
|
||||
test('recieves rows', function() {
|
||||
return false;
|
||||
test('sends execute message', function() {
|
||||
test('executing an unnamed portal with no row limit', function() {
|
||||
client.execute();
|
||||
assert.length(client.stream.packets, 1);
|
||||
var packet = client.stream.packets.pop();
|
||||
var expectedBuffer = new BufferList()
|
||||
.addCString('')
|
||||
.addInt32(0)
|
||||
.join(true,'E');
|
||||
assert.equalBuffers(packet, expectedBuffer);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('sends flush command', function() {
|
||||
client.flush();
|
||||
assert.length(client.stream.packets, 1);
|
||||
var packet = client.stream.packets.pop();
|
||||
var expected = new BufferList().join(true, 'H');
|
||||
assert.equalBuffers(packet, expected);
|
||||
});
|
||||
|
||||
test('sends sync command', function() {
|
||||
client.sync();
|
||||
assert.length(client.stream.packets, 1);
|
||||
var packet = client.stream.packets.pop();
|
||||
var expected = new BufferList().join(true,'S');
|
||||
assert.equalBuffers(packet, expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -81,4 +81,8 @@ buffers.parseComplete = function() {
|
||||
return new BufferList().join(true, '1');
|
||||
};
|
||||
|
||||
buffers.bindComplete = function() {
|
||||
return new BufferList().join(true, '2');
|
||||
};
|
||||
|
||||
module.exports = buffers;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user