mirror of
https://github.com/brianc/node-postgres.git
synced 2025-12-08 20:16:25 +00:00
parsing of prepared queries with no parameters
This commit is contained in:
parent
380abbf6a6
commit
95ec1b403c
@ -1,23 +1,24 @@
|
||||
BufferList = function() {
|
||||
this.buffers = [];
|
||||
};
|
||||
var p = BufferList.prototype;
|
||||
|
||||
BufferList.prototype.add = function(buffer, front) {
|
||||
p.add = function(buffer, front) {
|
||||
this.buffers[front ? "unshift" : "push"](buffer);
|
||||
return this;
|
||||
};
|
||||
|
||||
BufferList.prototype.addInt16 = function(val, front) {
|
||||
p.addInt16 = function(val, front) {
|
||||
return this.add(Buffer([(val >>> 8),(val >>> 0)]),front);
|
||||
};
|
||||
|
||||
BufferList.prototype.getByteLength = function(initial) {
|
||||
p.getByteLength = function(initial) {
|
||||
return this.buffers.reduce(function(previous, current){
|
||||
return previous + current.length;
|
||||
},initial || 0);
|
||||
};
|
||||
|
||||
BufferList.prototype.addInt32 = function(val, first) {
|
||||
p.addInt32 = function(val, first) {
|
||||
return this.add(Buffer([
|
||||
(val >>> 24 & 0xFF),
|
||||
(val >>> 16 & 0xFF),
|
||||
@ -26,15 +27,15 @@ BufferList.prototype.addInt32 = function(val, first) {
|
||||
]),first);
|
||||
};
|
||||
|
||||
BufferList.prototype.addCString = function(val) {
|
||||
p.addCString = function(val) {
|
||||
return this.add(Buffer(val + '\0','utf8'));
|
||||
};
|
||||
|
||||
BufferList.prototype.addChar = function(char, first) {
|
||||
p.addChar = function(char, first) {
|
||||
return this.add(Buffer(char,'utf8'), first);
|
||||
};
|
||||
|
||||
BufferList.prototype.join = function(appendLength, char) {
|
||||
p.join = function(appendLength, char) {
|
||||
var length = this.getByteLength();
|
||||
if(appendLength) {
|
||||
this.addInt32(length+4, true);
|
||||
@ -4,6 +4,7 @@ var crypto = require('crypto');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var utils = require(__dirname + '/utils');
|
||||
var BufferList = require(__dirname + '/buffer-list');
|
||||
|
||||
var Client = function(config) {
|
||||
EventEmitter.call(this);
|
||||
@ -28,7 +29,7 @@ sys.inherits(Client, EventEmitter);
|
||||
var p = Client.prototype;
|
||||
|
||||
p.connect = function() {
|
||||
if(this.stream.readyState == 'closed'){
|
||||
if(this.stream.readyState === 'closed'){
|
||||
this.stream.connect(this.port, this.host);
|
||||
}
|
||||
var self = this;
|
||||
@ -109,8 +110,23 @@ p.query = function(text) {
|
||||
return this;
|
||||
};
|
||||
|
||||
p.parse = function(text, types) {
|
||||
|
||||
p.parse = function(query) {
|
||||
//expect something like this:
|
||||
// { name: 'queryName',
|
||||
// text: 'select * from blah',
|
||||
// types: ['int8', 'bool'] }
|
||||
|
||||
//normalize missing query names to allow for null
|
||||
query.name = query.name || '';
|
||||
//normalize null type array
|
||||
query.types = query.types || [];
|
||||
|
||||
//append internal type identifier
|
||||
query.type = 'preparedQuery';
|
||||
|
||||
this.queryQueue.push(query);
|
||||
this.pulseQueryQueue();
|
||||
return this;
|
||||
};
|
||||
|
||||
p.pulseQueryQueue = function(ready) {
|
||||
@ -121,10 +137,22 @@ p.pulseQueryQueue = function(ready) {
|
||||
if(query) {
|
||||
var self = this;
|
||||
this.readyForQuery = false;
|
||||
if(query.type !== 'simpleQuery') {
|
||||
throw new Error("do not know how to handle this");
|
||||
if(query.type === 'simpleQuery') {
|
||||
this.send('Q', new Buffer(query.text + '\0', this.encoding));
|
||||
return;
|
||||
}
|
||||
this.send('Q', new Buffer(query.text + '\0', this.encoding));
|
||||
if(query.type === 'preparedQuery') {
|
||||
var buffer = new BufferList()
|
||||
.addCString(query.name) //name of query
|
||||
.addCString(query.text) //actual query text
|
||||
.addInt16(0).join();
|
||||
if(query.types.length) {
|
||||
sys.debug("Typed parameters not supported yet!");
|
||||
}
|
||||
this.send('P', buffer);
|
||||
return;
|
||||
}
|
||||
throw new Error("I don't know this query type " + sys.inspect(query));
|
||||
}
|
||||
};
|
||||
//query handling
|
||||
@ -242,16 +270,16 @@ p.parseMessage = function() {
|
||||
|
||||
p.parseR = function(msg) {
|
||||
var code = 0;
|
||||
if(msg.length == 8) {
|
||||
if(msg.length === 8) {
|
||||
code = this.parseInt32();
|
||||
if(code == 3) {
|
||||
if(code === 3) {
|
||||
msg.name = 'authenticationCleartextPassword';
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
if(msg.length == 12) {
|
||||
if(msg.length === 12) {
|
||||
code = this.parseInt32();
|
||||
if(code == 5) { //md5 required
|
||||
if(code === 5) { //md5 required
|
||||
msg.name = 'authenticationMD5Password';
|
||||
msg.salt = new Buffer(4);
|
||||
this.buffer.copy(msg.salt, 0, this.offset, this.offset + 4);
|
||||
@ -302,7 +330,7 @@ p.parseField = function() {
|
||||
dataTypeID: this.parseInt32(),
|
||||
dataTypeSize: this.parseInt16(),
|
||||
dataTypeModifier: this.parseInt32(),
|
||||
format: this.parseInt16() == 0 ? 'text' : 'binary'
|
||||
format: this.parseInt16() === 0 ? 'text' : 'binary'
|
||||
};
|
||||
return field;
|
||||
};
|
||||
@ -312,7 +340,7 @@ p.parseD = function(msg) {
|
||||
var fields = [];
|
||||
for(var i = 0; i < fieldCount; i++) {
|
||||
var length = this.parseInt32();
|
||||
fields[i] = (length == -1 ? null : this.readString(length))
|
||||
fields[i] = (length === -1 ? null : this.readString(length))
|
||||
};
|
||||
msg.fieldCount = fieldCount;
|
||||
msg.fields = fields;
|
||||
|
||||
@ -8,9 +8,31 @@ test('prepared queries', function() {
|
||||
|
||||
test("parse messages", function() {
|
||||
|
||||
test('parsing a query with no parameters', function() {
|
||||
client.parse('!');
|
||||
test('parsing a query with no parameters and no name', function() {
|
||||
client.parse({text: '!'});
|
||||
assert.length(client.stream.packets, 1);
|
||||
var expected = new BufferList()
|
||||
.addCString("")
|
||||
.addCString("!")
|
||||
.addInt16(0).join(true, 'P');
|
||||
assert.equalBuffers(client.stream.packets.pop(), expected);
|
||||
client.stream.emit('data', buffers.readyForQuery());
|
||||
});
|
||||
|
||||
test('parsing a query with a name', function() {
|
||||
//clear packets
|
||||
client.parse({
|
||||
name: 'boom',
|
||||
text: 'select * from boom',
|
||||
types: []
|
||||
});
|
||||
assert.length(client.stream.packets, 1);
|
||||
var expected = new BufferList()
|
||||
.addCString("boom")
|
||||
.addCString("select * from boom")
|
||||
.addInt16(0).join(true,'P');
|
||||
assert.equalBuffers(client.stream.packets.pop(), expected);
|
||||
client.stream.emit('data', buffers.readyForQuery());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -2,7 +2,7 @@ sys = require('sys');
|
||||
assert = require('assert');
|
||||
Client = require(__dirname+'/../../lib/client');
|
||||
EventEmitter = require('events').EventEmitter;
|
||||
BufferList = require(__dirname+'/buffer-list');
|
||||
BufferList = require(__dirname+'/../../lib/buffer-list');
|
||||
buffers = require(__dirname+'/test-buffers');
|
||||
|
||||
assert.same = function(actual, expected) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user