mirror of
https://github.com/brianc/node-postgres.git
synced 2025-12-08 20:16:25 +00:00
prepared statements moved forward a good deal
This commit is contained in:
parent
9d2c1e378c
commit
da8026df9d
@ -77,7 +77,7 @@ p.pulseQueryQueue = function() {
|
||||
|
||||
p.query = function(config) {
|
||||
//can take in strings or config objects
|
||||
var query = new Query(config.text ? config : { text: config });
|
||||
var query = new Query((config.text || config.name) ? config : { text: config });
|
||||
this.queryQueue.push(query);
|
||||
this.pulseQueryQueue();
|
||||
return query;
|
||||
@ -102,6 +102,7 @@ var Query = function(config) {
|
||||
this.rowDescription = null;
|
||||
EventEmitter.call(this);
|
||||
};
|
||||
|
||||
sys.inherits(Query, EventEmitter);
|
||||
var p = Query.prototype;
|
||||
|
||||
@ -132,16 +133,13 @@ p.submit = function(connection) {
|
||||
});
|
||||
};
|
||||
|
||||
p.hasBeenParsed = function(connection) {
|
||||
return this.name && connection.parsedStatements[this.name];
|
||||
};
|
||||
|
||||
p.prepare = function(connection) {
|
||||
var self = this;
|
||||
|
||||
connection.parse({
|
||||
text: self.text,
|
||||
name: self.name,
|
||||
types: self.types
|
||||
});
|
||||
connection.flush();
|
||||
|
||||
var onParseComplete = function() {
|
||||
connection.bind({
|
||||
portal: self.name,
|
||||
@ -151,7 +149,20 @@ p.prepare = function(connection) {
|
||||
connection.flush();
|
||||
};
|
||||
|
||||
connection.once('parseComplete', onParseComplete);
|
||||
|
||||
if(this.hasBeenParsed(connection)) {
|
||||
onParseComplete();
|
||||
} else {
|
||||
connection.parsedStatements[this.name] = true;
|
||||
connection.parse({
|
||||
text: self.text,
|
||||
name: self.name,
|
||||
types: self.types
|
||||
});
|
||||
connection.flush();
|
||||
connection.once('parseComplete', onParseComplete);
|
||||
}
|
||||
|
||||
|
||||
var onBindComplete = function() {
|
||||
connection.describe({
|
||||
|
||||
@ -15,6 +15,7 @@ var Connection = function(config) {
|
||||
this.buffer = null;
|
||||
this.offset = null;
|
||||
this.encoding = 'utf8';
|
||||
this.parsedStatements = {};
|
||||
};
|
||||
|
||||
sys.inherits(Connection, EventEmitter);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
var helper = require(__dirname +'/test-helper');
|
||||
|
||||
test("simple prepared statement", function(){
|
||||
test("simple, unnamed prepared statement", function(){
|
||||
var client = helper.client();
|
||||
|
||||
var query = client.query({
|
||||
@ -16,3 +16,138 @@ test("simple prepared statement", function(){
|
||||
client.end();
|
||||
});
|
||||
});
|
||||
|
||||
test("named prepared statement", function() {
|
||||
|
||||
var client = helper.client();
|
||||
var queryName = "user by age and like name";
|
||||
var query = client.query({
|
||||
text: 'select name from person where age <= $1 and name LIKE $2',
|
||||
values: [20, 'Bri%'],
|
||||
name: queryName
|
||||
});
|
||||
|
||||
var parseCount = 0;
|
||||
client.connection.on('parseComplete', function() {
|
||||
parseCount++;
|
||||
});
|
||||
|
||||
assert.raises(query, 'row', function(row) {
|
||||
assert.equal(row.fields[0], 'Brian');
|
||||
});
|
||||
|
||||
assert.raises(query, 'end', function() {
|
||||
test("query was parsed", function() {
|
||||
assert.equal(parseCount, 1);
|
||||
});
|
||||
|
||||
test("with same name & text", function() {
|
||||
var cachedQuery = client.query({
|
||||
text: 'select name from person where age <= $1 and name LIKE $2',
|
||||
name: queryName,
|
||||
values: [10, 'A%']
|
||||
});
|
||||
|
||||
assert.raises(cachedQuery, 'row', function(row) {
|
||||
assert.equal(row.fields[0], 'Aaron');
|
||||
});
|
||||
|
||||
assert.raises(cachedQuery, 'end', function() {
|
||||
test("query was only parsed one time", function() {
|
||||
assert.equal(parseCount, 1, "Should not have reparsed query");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("with same name, but the query text not even there batman!", function() {
|
||||
var q = client.query({
|
||||
name: queryName,
|
||||
values: [30, '%n%']
|
||||
});
|
||||
|
||||
test("gets first row", function() {
|
||||
|
||||
assert.raises(q, 'row', function(row) {
|
||||
assert.equal(row.fields[0], "Aaron");
|
||||
|
||||
test("gets second row", function() {
|
||||
|
||||
assert.raises(q, 'row', function(row) {
|
||||
assert.equal(row.fields[0], "Brian");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test("only parsed query once total", function() {
|
||||
assert.equal(parseCount, 1);
|
||||
q.on('end', function() {
|
||||
client.end();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test("prepared statements on different clients", function() {
|
||||
var statementName = "differ";
|
||||
var statement1 = "select count(*) from person";
|
||||
var statement2 = "select count(*) from person where age < $1";
|
||||
|
||||
var client1Finished = false;
|
||||
var client2Finished = false;
|
||||
|
||||
var client1 = helper.client();
|
||||
|
||||
var client2 = helper.client();
|
||||
|
||||
test("client 1 execution", function() {
|
||||
|
||||
var query = client1.query({
|
||||
name: statementName,
|
||||
text: statement1
|
||||
});
|
||||
test('gets right data back', function() {
|
||||
assert.raises(query, 'row', function(row) {
|
||||
assert.equal(row.fields[0], 26);
|
||||
});
|
||||
});
|
||||
|
||||
assert.raises(query, 'end', function() {
|
||||
if(client2Finished) {
|
||||
client1.end();
|
||||
client2.end();
|
||||
} else {
|
||||
client1Finished = true;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('client 2 execution', function() {
|
||||
var query = client2.query({
|
||||
name: statementName,
|
||||
text: statement2,
|
||||
values: [11]
|
||||
});
|
||||
|
||||
test('gets right data', function() {
|
||||
assert.raises(query, 'row', function(row) {
|
||||
assert.equal(row.fields[0], 1);
|
||||
});
|
||||
});
|
||||
|
||||
assert.raises(query, 'end', function() {
|
||||
if(client1Finished) {
|
||||
client1.end();
|
||||
client2.end();
|
||||
} else {
|
||||
client2Finished = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -3,68 +3,84 @@ var helper = require(__dirname + '/test-helper');
|
||||
var client = helper.client();
|
||||
var con = client.connection;
|
||||
var parseArg = null;
|
||||
con.parse = function(query) {
|
||||
parseArg = query;
|
||||
con.parse = function(arg) {
|
||||
parseArg = arg;
|
||||
process.nextTick(function() {
|
||||
con.emit('parseComplete');
|
||||
});
|
||||
};
|
||||
|
||||
var bindArg = null;
|
||||
con.bind = function(arg) {
|
||||
bindArg = arg;
|
||||
this.emit('bindComplete');
|
||||
process.nextTick(function(){
|
||||
con.emit('bindComplete');
|
||||
});
|
||||
};
|
||||
|
||||
var executeArg = null;
|
||||
con.execute = function(arg) {
|
||||
executeArg = arg;
|
||||
this.emit('rowData',{ fields: [] });
|
||||
this.emit('commandComplete');
|
||||
process.nextTick(function() {
|
||||
con.emit('rowData',{ fields: [] });
|
||||
con.emit('commandComplete');
|
||||
});
|
||||
};
|
||||
|
||||
var describeArg = null;
|
||||
con.describe = function(arg) {
|
||||
describeArg = arg;
|
||||
this.emit('rowDescription', { fields: [] });
|
||||
process.nextTick(function() {
|
||||
con.emit('rowDescription', { fields: [] });
|
||||
});
|
||||
};
|
||||
|
||||
var syncCalled = true;
|
||||
var syncCalled = false;
|
||||
con.flush = function() {
|
||||
};
|
||||
con.sync = function() {
|
||||
syncCalled = false;
|
||||
this.emit('readyForQuery')
|
||||
syncCalled = true;
|
||||
process.nextTick(function() {
|
||||
con.emit('readyForQuery');
|
||||
});
|
||||
};
|
||||
|
||||
test('bound command', function() {
|
||||
test('simple, unnamed bound command', function() {
|
||||
return false;
|
||||
assert.ok(client.connection.emit('readyForQuery'));
|
||||
|
||||
var query = client.query({
|
||||
text: 'select * where name = $1',
|
||||
parameters: ['hi']
|
||||
values: ['hi']
|
||||
});
|
||||
|
||||
test('parse argument', function() {
|
||||
assert.equal(parseArg.name, null);
|
||||
assert.equal(parseArg.text, 'select * where name = $1');
|
||||
assert.equal(parseArg.types, null);
|
||||
});
|
||||
assert.raises(query,'end', function() {
|
||||
test('parse argument', function() {
|
||||
assert.equal(parseArg.name, null);
|
||||
assert.equal(parseArg.text, 'select * where name = $1');
|
||||
assert.equal(parseArg.types, null);
|
||||
});
|
||||
|
||||
test('bind argument', function() {
|
||||
assert.equal(bindArg.statement, null);
|
||||
assert.equal(bindArg.portal, null);
|
||||
assert.length(bindArg.values, 1);
|
||||
assert.equal(bindArg.values[0], 'hi')
|
||||
});
|
||||
test('bind argument', function() {
|
||||
assert.equal(bindArg.statement, null);
|
||||
assert.equal(bindArg.portal, null);
|
||||
assert.length(bindArg.values, 1);
|
||||
assert.equal(bindArg.values[0], 'hi')
|
||||
});
|
||||
|
||||
test('describe argument', function() {
|
||||
assert.equal(describeArg, null);
|
||||
});
|
||||
test('describe argument', function() {
|
||||
assert.equal(describeArg.type, 'P');
|
||||
assert.equal(describeArg.name, "");
|
||||
});
|
||||
|
||||
test('execute argument', function() {
|
||||
assert.equal(executeArg.portal, null);
|
||||
assert.equal(executeArg.rows, null);
|
||||
});
|
||||
test('execute argument', function() {
|
||||
assert.equal(executeArg.portal, null);
|
||||
assert.equal(executeArg.rows, null);
|
||||
});
|
||||
|
||||
test('sync called', function() {
|
||||
assert.ok(syncCalled);
|
||||
test('sync called', function() {
|
||||
assert.ok(syncCalled);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user