@@ -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,9 +1530,10 @@ 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 data read out of the provided `Read`er are passed to the Postgres
1534+ /// server verbatim; it is the caller's responsibility to ensure the data
1535+ /// is in the proper format. See the
1536+ /// [Postgres documentation](http://www.postgresql.org/docs/9.4/static/sql-copy.html)
15361537 /// for details.
15371538 ///
15381539 /// If the statement is not a `COPY FROM STDIN` statement, it will still be
@@ -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