4141//! }
4242//! }
4343//! ```
44- #![ doc( html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.2 " ) ]
44+ #![ doc( html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.3 " ) ]
4545#![ warn( missing_docs) ]
4646
4747extern crate bufstream;
@@ -73,7 +73,7 @@ use std::path::PathBuf;
7373use error:: { Error , ConnectError , SqlState , DbError } ;
7474use types:: { ToSql , FromSql } ;
7575use io:: { StreamWrapper , NegotiateSsl } ;
76- use types:: { IsNull , Kind , Type , SessionInfo , Oid , Other } ;
76+ use types:: { IsNull , Kind , Type , SessionInfo , Oid , Other , ReadWithInfo } ;
7777use message:: BackendMessage :: * ;
7878use message:: FrontendMessage :: * ;
7979use message:: { FrontendMessage , BackendMessage , RowDescriptionEntry } ;
@@ -1530,12 +1530,13 @@ impl<'conn> Statement<'conn> {
15301530 /// Executes a `COPY FROM STDIN` statement, returning the number of rows
15311531 /// added.
15321532 ///
1533- /// The contents of the provided `Read`er are passed to the Postgres server
1534- /// verbatim; it is the caller's responsibility to ensure the data is in
1535- /// the proper format. See the [Postgres documentation](http://www.postgresql.org/docs/9.4/static/sql-copy.html)
1533+ /// The contents of the provided reader are passed to the Postgres server
1534+ /// verbatim; it is the caller's responsibility to ensure it uses the
1535+ /// proper format. See the
1536+ /// [Postgres documentation](http://www.postgresql.org/docs/9.4/static/sql-copy.html)
15361537 /// for details.
15371538 ///
1538- /// If the statement is not a `COPY FROM STDIN` statement, it will still be
1539+ /// If the statement is not a `COPY FROM STDIN` statement it will still be
15391540 /// executed and this method will return an error.
15401541 ///
15411542 /// # Examples
@@ -1547,7 +1548,7 @@ impl<'conn> Statement<'conn> {
15471548 /// let stmt = conn.prepare("COPY people FROM STDIN").unwrap();
15481549 /// stmt.copy_in(&[], &mut "1\tjohn\n2\tjane\n".as_bytes()).unwrap();
15491550 /// ```
1550- pub fn copy_in < R : Read > ( & self , params : & [ & ToSql ] , r : & mut R ) -> Result < u64 > {
1551+ pub fn copy_in < R : ReadWithInfo > ( & self , params : & [ & ToSql ] , r : & mut R ) -> Result < u64 > {
15511552 try!( self . inner_execute ( "" , 0 , params) ) ;
15521553 let mut conn = self . conn . conn . borrow_mut ( ) ;
15531554
@@ -1567,16 +1568,15 @@ impl<'conn> Statement<'conn> {
15671568 }
15681569 }
15691570
1570- let mut buf = vec ! [ ] ;
1571+ let mut buf = [ 0 ; 16 * 1024 ] ;
15711572 loop {
1572- match r . take ( 16 * 1024 ) . read_to_end ( & mut buf) {
1573+ match fill_copy_buf ( & mut buf, r , & SessionInfo :: new ( & conn ) ) {
15731574 Ok ( 0 ) => break ,
1574- Ok ( _ ) => {
1575+ Ok ( len ) => {
15751576 try_desync ! ( conn, conn. stream. write_message(
15761577 & CopyData {
1577- data: & buf,
1578+ data: & buf[ ..len ] ,
15781579 } ) ) ;
1579- buf. clear ( ) ;
15801580 }
15811581 Err ( err) => {
15821582 try!( conn. write_messages ( & [
@@ -1628,6 +1628,20 @@ impl<'conn> Statement<'conn> {
16281628 }
16291629}
16301630
1631+ fn fill_copy_buf < R : ReadWithInfo > ( buf : & mut [ u8 ] , r : & mut R , info : & SessionInfo )
1632+ -> std_io:: Result < usize > {
1633+ let mut nread = 0 ;
1634+ while nread < buf. len ( ) {
1635+ match r. read_with_info ( & mut buf[ nread..] , info) {
1636+ Ok ( 0 ) => break ,
1637+ Ok ( n) => nread += n,
1638+ Err ( ref e) if e. kind ( ) == std_io:: ErrorKind :: Interrupted => { }
1639+ Err ( e) => return Err ( e) ,
1640+ }
1641+ }
1642+ Ok ( nread)
1643+ }
1644+
16311645/// Information about a column of the result of a query.
16321646#[ derive( PartialEq , Eq , Clone , Debug ) ]
16331647pub struct Column {
0 commit comments