Skip to content

Commit 0f1d31c

Browse files
committed
Batch command sequence writes
This allows command sequences like Prepare/Describe/Sync to be sent in fewer TCP packets.
1 parent 557c61d commit 0f1d31c

1 file changed

Lines changed: 48 additions & 30 deletions

File tree

src/lib.rs

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use extra::md5::Md5;
55
use extra::url::{UserInfo, Url};
66
use std::cell::Cell;
77
use std::hashmap::HashMap;
8-
use std::rt::io::io_error;
8+
use std::rt::io::{io_error, Decorator};
9+
use std::rt::io::mem::MemWriter;
910
use std::rt::io::net::ip::SocketAddr;
1011
use std::rt::io::net::tcp::TcpStream;
1112

@@ -183,6 +184,16 @@ impl PostgresConnection {
183184
Ok(conn)
184185
}
185186
187+
fn write_messages(&self, messages: &[&FrontendMessage]) {
188+
let mut buf = MemWriter::new();
189+
for &message in messages.iter() {
190+
buf.write_message(message);
191+
}
192+
do self.stream.with_mut_ref |s| {
193+
s.write(buf.inner_ref().as_slice());
194+
}
195+
}
196+
186197
fn write_message(&self, message: &FrontendMessage) {
187198
do self.stream.with_mut_ref |s| {
188199
s.write_message(message);
@@ -249,13 +260,17 @@ impl PostgresConnection {
249260
self.next_stmt_id.put_back(id + 1);
250261
251262
let types = [];
252-
self.write_message(&Parse {
253-
name: stmt_name,
254-
query: query,
255-
param_types: types
256-
});
257-
self.write_message(&Describe { variant: 'S' as u8, name: stmt_name });
258-
self.write_message(&Sync);
263+
self.write_messages([
264+
&Parse {
265+
name: stmt_name,
266+
query: query,
267+
param_types: types
268+
},
269+
&Describe {
270+
variant: 'S' as u8,
271+
name: stmt_name
272+
},
273+
&Sync]);
259274
260275
match_read_message!(self, {
261276
ParseComplete => (),
@@ -371,11 +386,12 @@ pub struct PostgresStatement<'self> {
371386
impl<'self> Drop for PostgresStatement<'self> {
372387
fn drop(&self) {
373388
do io_error::cond.trap(|_| {}).inside {
374-
self.conn.write_message(&Close {
375-
variant: 'S' as u8,
376-
name: self.name.as_slice()
377-
});
378-
self.conn.write_message(&Sync);
389+
self.conn.write_messages([
390+
&Close {
391+
variant: 'S' as u8,
392+
name: self.name.as_slice()
393+
},
394+
&Sync]);
379395
loop {
380396
match_read_message!(self.conn, {
381397
ReadyForQuery {_} => break,
@@ -399,18 +415,19 @@ impl<'self> PostgresStatement<'self> {
399415
400416
let result_formats = [];
401417
402-
self.conn.write_message(&Bind {
403-
portal: portal_name,
404-
statement: self.name.as_slice(),
405-
formats: formats,
406-
values: values,
407-
result_formats: result_formats
408-
});
409-
self.conn.write_message(&Execute {
410-
portal: portal_name.as_slice(),
411-
max_rows: 0
412-
});
413-
self.conn.write_message(&Sync);
418+
self.conn.write_messages([
419+
&Bind {
420+
portal: portal_name,
421+
statement: self.name.as_slice(),
422+
formats: formats,
423+
values: values,
424+
result_formats: result_formats
425+
},
426+
&Execute {
427+
portal: portal_name.as_slice(),
428+
max_rows: 0
429+
},
430+
&Sync]);
414431
415432
match_read_message!(self.conn, {
416433
BindComplete => None,
@@ -521,11 +538,12 @@ pub struct PostgresResult<'self> {
521538
impl<'self> Drop for PostgresResult<'self> {
522539
fn drop(&self) {
523540
do io_error::cond.trap(|_| {}).inside {
524-
self.stmt.conn.write_message(&Close {
525-
variant: 'P' as u8,
526-
name: self.name.as_slice()
527-
});
528-
self.stmt.conn.write_message(&Sync);
541+
self.stmt.conn.write_messages([
542+
&Close {
543+
variant: 'P' as u8,
544+
name: self.name.as_slice()
545+
},
546+
&Sync]);
529547
loop {
530548
match_read_message!(self.stmt.conn, {
531549
ReadyForQuery {_} => break,

0 commit comments

Comments
 (0)