@@ -1346,24 +1346,17 @@ impl<'conn> Statement<'conn> {
13461346 }
13471347 }
13481348
1349- fn inner_lazy_query < ' a > ( & ' a self , row_limit : i32 , params : & [ & ToSql ] ) -> Result < Rows < ' a > > {
1350- let id = self . next_portal_id . get ( ) ;
1351- self . next_portal_id . set ( id + 1 ) ;
1352- let portal_name = format ! ( "{}p{}" , self . name, id) ;
1353-
1354- try!( self . inner_execute ( & * portal_name, row_limit, params) ) ;
1349+ fn inner_query < ' a > ( & ' a self , portal_name : & str , row_limit : i32 , params : & [ & ToSql ] )
1350+ -> Result < ( Rows < ' a > , bool ) > {
1351+ try!( self . inner_execute ( portal_name, row_limit, params) ) ;
13551352
13561353 let mut result = Rows {
13571354 stmt : self ,
1358- name : portal_name,
13591355 data : RingBuf :: new ( ) ,
1360- row_limit : row_limit,
1361- more_rows : true ,
1362- finished : false ,
13631356 } ;
1364- try!( result. read_rows ( ) ) ;
1357+ let more_rows = try!( result. read_rows ( ) ) ;
13651358
1366- Ok ( result)
1359+ Ok ( ( result, more_rows ) )
13671360 }
13681361
13691362 /// Returns a slice containing the expected parameter types.
@@ -1453,7 +1446,7 @@ impl<'conn> Statement<'conn> {
14531446 /// ```
14541447 pub fn query < ' a > ( & ' a self , params : & [ & ToSql ] ) -> Result < Rows < ' a > > {
14551448 check_desync ! ( self . conn) ;
1456- self . inner_lazy_query ( 0 , params)
1449+ self . inner_query ( "" , 0 , params) . map ( |t| t . 0 )
14571450 }
14581451
14591452 /// Executes the prepared statement, returning a lazily loaded iterator
@@ -1481,12 +1474,24 @@ impl<'conn> Statement<'conn> {
14811474 return Err ( Error :: WrongTransaction ) ;
14821475 }
14831476 drop ( conn) ;
1484- self . inner_lazy_query ( row_limit, params) . map ( |result| {
1485- LazyRows {
1486- _trans : trans,
1487- result : result
1477+
1478+ let id = self . next_portal_id . get ( ) ;
1479+ self . next_portal_id . set ( id + 1 ) ;
1480+ let portal_name = format ! ( "{}p{}" , self . name, id) ;
1481+
1482+ match self . inner_query ( & * portal_name, row_limit, params) {
1483+ Ok ( ( result, more_rows) ) => {
1484+ Ok ( LazyRows {
1485+ _trans : trans,
1486+ result : result,
1487+ name : portal_name,
1488+ row_limit : row_limit,
1489+ more_rows : more_rows,
1490+ finished : false ,
1491+ } )
14881492 }
1489- } )
1493+ Err ( err) => Err ( err) ,
1494+ }
14901495 }
14911496
14921497 /// Consumes the statement, clearing it from the Postgres session.
@@ -1510,46 +1515,27 @@ pub struct ResultDescription {
15101515/// An iterator over the resulting rows of a query.
15111516pub struct Rows < ' stmt > {
15121517 stmt : & ' stmt Statement < ' stmt > ,
1513- name : String ,
15141518 data : RingBuf < Vec < Option < Vec < u8 > > > > ,
1515- row_limit : i32 ,
1516- more_rows : bool ,
1517- finished : bool ,
15181519}
15191520
15201521impl < ' a > fmt:: Debug for Rows < ' a > {
15211522 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
1522- write ! ( fmt, "Rows {{ statement: {:?}, name: {:?}, remaining_rows: {:?} }}" ,
1523- self . stmt, self . name, self . data. len( ) )
1524- }
1525- }
1526-
1527- #[ unsafe_destructor]
1528- impl < ' stmt > Drop for Rows < ' stmt > {
1529- fn drop ( & mut self ) {
1530- if !self . finished {
1531- let _ = self . finish_inner ( ) ;
1532- }
1523+ write ! ( fmt, "Rows {{ statement: {:?}, remaining_rows: {:?} }}" , self . stmt, self . data. len( ) )
15331524 }
15341525}
15351526
15361527impl < ' stmt > Rows < ' stmt > {
1537- fn finish_inner ( & mut self ) -> Result < ( ) > {
1538- let mut conn = self . stmt . conn . conn . borrow_mut ( ) ;
1539- check_desync ! ( conn) ;
1540- conn. close_statement ( & * self . name , b'P' )
1541- }
1542-
1543- fn read_rows ( & mut self ) -> Result < ( ) > {
1528+ fn read_rows ( & mut self ) -> Result < bool > {
15441529 let mut conn = self . stmt . conn . conn . borrow_mut ( ) ;
1530+ let more_rows;
15451531 loop {
15461532 match try!( conn. read_message ( ) ) {
15471533 EmptyQueryResponse | CommandComplete { .. } => {
1548- self . more_rows = false ;
1534+ more_rows = false ;
15491535 break ;
15501536 }
15511537 PortalSuspended => {
1552- self . more_rows = true ;
1538+ more_rows = true ;
15531539 break ;
15541540 }
15551541 DataRow { row } => self . data . push_back ( row) ,
@@ -1570,41 +1556,19 @@ impl<'stmt> Rows<'stmt> {
15701556 }
15711557 }
15721558 }
1573- conn. wait_for_ready ( )
1574- }
1575-
1576- fn execute ( & mut self ) -> Result < ( ) > {
1577- try!( self . stmt . conn . write_messages ( & [
1578- Execute {
1579- portal : & * self . name ,
1580- max_rows : self . row_limit
1581- } ,
1582- Sync ] ) ) ;
1583- self . read_rows ( )
1559+ try!( conn. wait_for_ready ( ) ) ;
1560+ Ok ( more_rows)
15841561 }
15851562
15861563 /// Returns a slice describing the columns of the `Rows`.
15871564 pub fn result_descriptions ( & self ) -> & ' stmt [ ResultDescription ] {
15881565 self . stmt . result_descriptions ( )
15891566 }
15901567
1591- /// Consumes the `Rows`, cleaning up associated state.
1592- ///
1593- /// Functionally identical to the `Drop` implementation on `Rows`
1594- /// except that it returns any error to the caller.
1595- pub fn finish ( mut self ) -> Result < ( ) > {
1596- self . finished = true ;
1597- self . finish_inner ( )
1598- }
1599-
1600- fn try_next ( & mut self ) -> Option < Result < Row < ' stmt > > > {
1601- if self . data . is_empty ( ) && self . more_rows {
1602- if let Err ( err) = self . execute ( ) {
1603- return Some ( Err ( err) ) ;
1604- }
1605- }
1606-
1607- self . data . pop_front ( ) . map ( |row| Ok ( Row { stmt : self . stmt , data : row } ) )
1568+ #[ deprecated = "now a no-op" ]
1569+ #[ allow( missing_docs) ]
1570+ pub fn finish ( self ) -> Result < ( ) > {
1571+ Ok ( ( ) )
16081572 }
16091573}
16101574
@@ -1613,19 +1577,12 @@ impl<'stmt> Iterator for Rows<'stmt> {
16131577
16141578 #[ inline]
16151579 fn next ( & mut self ) -> Option < Row < ' stmt > > {
1616- // we'll never hit the network on a non-lazy result
1617- self . try_next ( ) . map ( |r| r. unwrap ( ) )
1580+ self . data . pop_front ( ) . map ( |row| Row { stmt : self . stmt , data : row } )
16181581 }
16191582
16201583 #[ inline]
16211584 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1622- let lower = self . data . len ( ) ;
1623- let upper = if self . more_rows {
1624- None
1625- } else {
1626- Some ( lower)
1627- } ;
1628- ( lower, upper)
1585+ ( self . data . len ( ) , Some ( self . data . len ( ) ) )
16291586 }
16301587}
16311588
@@ -1721,38 +1678,90 @@ impl<'a> RowIndex for &'a str {
17211678/// A lazily-loaded iterator over the resulting rows of a query
17221679pub struct LazyRows < ' trans , ' stmt > {
17231680 result : Rows < ' stmt > ,
1681+ name : String ,
1682+ row_limit : i32 ,
1683+ more_rows : bool ,
1684+ finished : bool ,
17241685 _trans : & ' trans Transaction < ' trans > ,
17251686}
17261687
1688+ #[ unsafe_destructor]
1689+ impl < ' a , ' b > Drop for LazyRows < ' a , ' b > {
1690+ fn drop ( & mut self ) {
1691+ if !self . finished {
1692+ let _ = self . finish_inner ( ) ;
1693+ }
1694+ }
1695+ }
1696+
17271697impl < ' a , ' b > fmt:: Debug for LazyRows < ' a , ' b > {
17281698 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
17291699 write ! ( fmt,
17301700 "LazyRows {{ statement: {:?}, name: {:?}, row_limit: {:?}, remaining_rows: {:?}, \
17311701 more_rows: {:?} }}",
17321702 self . result. stmt,
1733- self . result . name,
1734- self . result . row_limit,
1703+ self . name,
1704+ self . row_limit,
17351705 self . result. data. len( ) ,
1736- self . result . more_rows)
1706+ self . more_rows)
17371707 }
17381708}
17391709
17401710impl < ' trans , ' stmt > LazyRows < ' trans , ' stmt > {
1741- /// Like `Rows::finish`.
1742- pub fn finish ( self ) -> Result < ( ) > {
1743- self . result . finish ( )
1711+ fn finish_inner ( & mut self ) -> Result < ( ) > {
1712+ let mut conn = self . result . stmt . conn . conn . borrow_mut ( ) ;
1713+ check_desync ! ( conn) ;
1714+ conn. close_statement ( & * self . name , b'P' )
1715+ }
1716+
1717+ fn execute ( & mut self ) -> Result < ( ) > {
1718+ try!( self . result . stmt . conn . write_messages ( & [
1719+ Execute {
1720+ portal : & * self . name ,
1721+ max_rows : self . row_limit
1722+ } ,
1723+ Sync ] ) ) ;
1724+ self . result . read_rows ( ) . map ( |more_rows| {
1725+ self . more_rows = more_rows;
1726+ ( )
1727+ } )
1728+ }
1729+
1730+ /// Returns a slice describing the columns of the `Rows`.
1731+ pub fn result_descriptions ( & self ) -> & ' stmt [ ResultDescription ] {
1732+ self . result . stmt . result_descriptions ( )
1733+ }
1734+
1735+ /// Consumes the `LazyRows`, cleaning up associated state.
1736+ ///
1737+ /// Functionally identical to the `Drop` implementation on `LazyRows`
1738+ /// except that it returns any error to the caller.
1739+ pub fn finish ( mut self ) -> Result < ( ) > {
1740+ self . finish_inner ( )
17441741 }
17451742}
17461743
17471744impl < ' trans , ' stmt > Iterator for LazyRows < ' trans , ' stmt > {
17481745 type Item = Result < Row < ' stmt > > ;
17491746
17501747 fn next ( & mut self ) -> Option < Result < Row < ' stmt > > > {
1751- self . result . try_next ( )
1748+ if self . result . data . is_empty ( ) && self . more_rows {
1749+ if let Err ( err) = self . execute ( ) {
1750+ return Some ( Err ( err) ) ;
1751+ }
1752+ }
1753+
1754+ self . result . next ( ) . map ( |r| Ok ( r) )
17521755 }
17531756
17541757 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1755- self . result . size_hint ( )
1758+ let lower = self . result . data . len ( ) ;
1759+ let upper = if self . more_rows {
1760+ None
1761+ } else {
1762+ Some ( lower)
1763+ } ;
1764+ ( lower, upper)
17561765 }
17571766}
17581767
0 commit comments