Skip to content

Commit 104727f

Browse files
committed
simple prepared statements working!
1 parent 35d2b2e commit 104727f

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

lib/client.js

+49-3
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ var Query = function(config) {
105105
sys.inherits(Query, EventEmitter);
106106
var p = Query.prototype;
107107

108-
p.isBoundCommand = function() {
108+
p.requiresPreparation = function() {
109109
return (this.values || 0).length > 0 || this.name || this.rows;
110110
};
111111

112112
p.submit = function(connection) {
113113
var self = this;
114-
if(this.isBoundCommand()) {
115-
throw new Error('Bound command not supported yet! :(');
114+
if(this.requiresPreparation()) {
115+
this.prepare(connection);
116116
} else {
117117
connection.query(this.text);
118118
}
@@ -132,6 +132,52 @@ p.submit = function(connection) {
132132
});
133133
};
134134

135+
p.prepare = function(connection) {
136+
var self = this;
137+
138+
connection.parse({
139+
text: self.text,
140+
name: self.name,
141+
types: self.types
142+
});
143+
connection.flush();
144+
145+
var onParseComplete = function() {
146+
connection.bind({
147+
portal: self.name,
148+
statement: self.name,
149+
values: self.values
150+
});
151+
connection.flush();
152+
};
153+
154+
connection.once('parseComplete', onParseComplete);
155+
156+
var onBindComplete = function() {
157+
connection.describe({
158+
type: 'P',
159+
name: self.name || ""
160+
});
161+
//http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
162+
//TODO get ourselves a rowDescription for result type coercion
163+
connection.execute({
164+
portal: self.name,
165+
rows: self.rows
166+
});
167+
connection.flush();
168+
};
169+
170+
connection.once('bindComplete', onBindComplete);
171+
172+
//TODO support EmptyQueryResponse, ErrorResponse, and PortalSuspended
173+
var onCommandComplete = function() {
174+
connection.sync();
175+
};
176+
connection.once('commandComplete', onCommandComplete);
177+
178+
};
179+
180+
135181
p.onRowDescription = function(msg) {
136182
var typeIds = msg.fields.map(function(field) {
137183
return field.dataTypeID;

lib/connection.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ p.end = function() {
165165
};
166166

167167
p.describe = function(msg) {
168-
this.send('D',Buffer(msg.type+msg.name+'\0'));
168+
var str = msg.type + (msg.name || "" ) + '\0';
169+
var buffer = Buffer(str, this.encoding);
170+
this.send('D', buffer);
169171
};
170172

171173
//parsing methods
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var helper = require(__dirname +'/test-helper');
2+
3+
test("simple prepared statement", function(){
4+
var client = helper.client();
5+
client.connection.on('message', function(msg) {
6+
console.log(msg.name);
7+
});
8+
var query = client.query({
9+
text: 'select age from person where name = $1',
10+
values: ['Brian']
11+
});
12+
13+
assert.raises(query, 'row', function(row) {
14+
assert.equal(row.fields[0], 20);
15+
});
16+
17+
assert.raises(query, 'end', function() {
18+
client.end();
19+
});
20+
});

test/unit/connection/outbound-sending-tests.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,14 @@ test('sends end command', function() {
158158

159159
test('sends describe command',function() {
160160
test('describe statement', function() {
161-
con.describe({type: 's', name: 'bang'});
162-
var expected = new BufferList().addChar('s').addCString('bang').join(true, 'D')
161+
con.describe({type: 'S', name: 'bang'});
162+
var expected = new BufferList().addChar('S').addCString('bang').join(true, 'D')
163+
assert.recieved(stream, expected);
164+
});
165+
166+
test("describe unnamed portal", function() {
167+
con.describe({type: 'P'});
168+
var expected = new BufferList().addChar('P').addCString("").join(true, "D");
163169
assert.recieved(stream, expected);
164170
});
165171
});

0 commit comments

Comments
 (0)