@@ -85,6 +85,7 @@ use std::collections::{VecDeque, HashMap};
85
85
use std:: fmt;
86
86
use std:: io;
87
87
use std:: mem;
88
+ use std:: ops:: Range ;
88
89
use std:: result;
89
90
use std:: sync:: Arc ;
90
91
use std:: time:: Duration ;
@@ -488,7 +489,9 @@ impl InnerConnection {
488
489
Ok ( ( param_types, columns) )
489
490
}
490
491
491
- fn read_rows ( & mut self , buf : & mut VecDeque < Vec < Option < Vec < u8 > > > > ) -> Result < bool > {
492
+ fn read_rows < F > ( & mut self , mut consumer : F ) -> Result < bool >
493
+ where F : FnMut ( RowData )
494
+ {
492
495
let more_rows;
493
496
loop {
494
497
match try!( self . read_message ( ) ) {
@@ -502,8 +505,12 @@ impl InnerConnection {
502
505
break ;
503
506
}
504
507
backend:: Message :: DataRow ( body) => {
505
- let row = try!( body. values ( ) . map ( |v| v. map ( ToOwned :: to_owned) ) . collect ( ) ) ;
506
- buf. push_back ( row) ;
508
+ let mut row = RowData :: new ( ) ;
509
+ let mut it = body. values ( ) ;
510
+ while let Some ( value) = try!( it. next ( ) ) {
511
+ row. push ( value) ;
512
+ }
513
+ consumer ( row) ;
507
514
}
508
515
backend:: Message :: ErrorResponse ( body) => {
509
516
try!( self . wait_for_ready ( ) ) ;
@@ -694,12 +701,11 @@ impl InnerConnection {
694
701
fn read_type ( & mut self , oid : Oid ) -> Result < Other > {
695
702
try!( self . setup_typeinfo_query ( ) ) ;
696
703
try!( self . raw_execute ( TYPEINFO_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & oid] ) ) ;
697
- let mut rows = VecDeque :: new ( ) ;
698
- try!( self . read_rows ( & mut rows) ) ;
699
- let row = rows. pop_front ( ) ;
704
+ let mut row = None ;
705
+ try!( self . read_rows ( |r| row = Some ( r) ) ) ;
700
706
701
707
let get_raw = |i : usize | {
702
- row. as_ref ( ) . and_then ( |r| r. get ( i) ) . and_then ( |r| r . as_ref ( ) . map ( |r| & * * r ) )
708
+ row. as_ref ( ) . and_then ( |r| r. get ( i) )
703
709
} ;
704
710
705
711
let ( name, type_, elem_oid, rngsubtype, basetype, schema, relid) = {
@@ -770,14 +776,13 @@ impl InnerConnection {
770
776
fn read_enum_variants ( & mut self , oid : Oid ) -> Result < Vec < String > > {
771
777
try!( self . setup_typeinfo_enum_query ( ) ) ;
772
778
try!( self . raw_execute ( TYPEINFO_ENUM_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & oid] ) ) ;
773
- let mut rows = VecDeque :: new ( ) ;
774
- try!( self . read_rows ( & mut rows) ) ;
779
+ let mut rows = vec ! [ ] ;
780
+ try!( self . read_rows ( |row| rows. push ( row ) ) ) ;
775
781
776
782
let ctx = SessionInfo :: new ( & self . parameters ) ;
777
783
let mut variants = vec ! [ ] ;
778
784
for row in rows {
779
- let raw = row. get ( 0 ) . and_then ( |r| r. as_ref ( ) . map ( |r| & * * r) ) ;
780
- variants. push ( try!( String :: from_sql_nullable ( & Type :: Name , raw, & ctx)
785
+ variants. push ( try!( String :: from_sql_nullable ( & Type :: Name , row. get ( 0 ) , & ctx)
781
786
. map_err ( Error :: Conversion ) ) ) ;
782
787
}
783
788
@@ -804,17 +809,16 @@ impl InnerConnection {
804
809
fn read_composite_fields ( & mut self , relid : Oid ) -> Result < Vec < Field > > {
805
810
try!( self . setup_typeinfo_composite_query ( ) ) ;
806
811
try!( self . raw_execute ( TYPEINFO_COMPOSITE_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & relid] ) ) ;
807
- let mut rows = VecDeque :: new ( ) ;
808
- try!( self . read_rows ( & mut rows) ) ;
812
+ let mut rows = vec ! [ ] ;
813
+ try!( self . read_rows ( |row| rows. push ( row ) ) ) ;
809
814
810
815
let mut fields = vec ! [ ] ;
811
816
for row in rows {
812
817
let ( name, type_) = {
813
- let get_raw = |i : usize | row. get ( i) . and_then ( |r| r. as_ref ( ) . map ( |r| & * * r) ) ;
814
818
let ctx = SessionInfo :: new ( & self . parameters ) ;
815
- let name = try!( String :: from_sql_nullable ( & Type :: Name , get_raw ( 0 ) , & ctx)
819
+ let name = try!( String :: from_sql_nullable ( & Type :: Name , row . get ( 0 ) , & ctx)
816
820
. map_err ( Error :: Conversion ) ) ;
817
- let type_ = try!( Oid :: from_sql_nullable ( & Type :: Oid , get_raw ( 1 ) , & ctx)
821
+ let type_ = try!( Oid :: from_sql_nullable ( & Type :: Oid , row . get ( 1 ) , & ctx)
818
822
. map_err ( Error :: Conversion ) ) ;
819
823
( name, type_)
820
824
} ;
@@ -1329,6 +1333,43 @@ impl<'a> GenericConnection for Transaction<'a> {
1329
1333
}
1330
1334
}
1331
1335
1336
+ struct RowData {
1337
+ buf : Vec < u8 > ,
1338
+ indices : Vec < Option < Range < usize > > > ,
1339
+ }
1340
+
1341
+ impl RowData {
1342
+ fn new ( ) -> RowData {
1343
+ RowData {
1344
+ buf : vec ! [ ] ,
1345
+ indices : vec ! [ ] ,
1346
+ }
1347
+ }
1348
+
1349
+ fn push ( & mut self , cell : Option < & [ u8 ] > ) {
1350
+ let index = match cell {
1351
+ Some ( cell) => {
1352
+ let base = self . buf . len ( ) ;
1353
+ self . buf . extend_from_slice ( cell) ;
1354
+ Some ( base..self . buf . len ( ) )
1355
+ }
1356
+ None => None ,
1357
+ } ;
1358
+ self . indices . push ( index) ;
1359
+ }
1360
+
1361
+ fn len ( & self ) -> usize {
1362
+ self . indices . len ( )
1363
+ }
1364
+
1365
+ fn get ( & self , index : usize ) -> Option < & [ u8 ] > {
1366
+ match & self . indices [ index] {
1367
+ & Some ( ref range) => Some ( & self . buf [ range. clone ( ) ] ) ,
1368
+ & None => None ,
1369
+ }
1370
+ }
1371
+ }
1372
+
1332
1373
trait OtherNew {
1333
1374
fn new ( name : String , oid : Oid , kind : Kind , schema : String ) -> Other ;
1334
1375
}
@@ -1340,13 +1381,13 @@ trait DbErrorNew {
1340
1381
}
1341
1382
1342
1383
trait RowsNew < ' a > {
1343
- fn new ( stmt : & ' a Statement < ' a > , data : Vec < Vec < Option < Vec < u8 > > > > ) -> Rows < ' a > ;
1344
- fn new_owned ( stmt : Statement < ' a > , data : Vec < Vec < Option < Vec < u8 > > > > ) -> Rows < ' a > ;
1384
+ fn new ( stmt : & ' a Statement < ' a > , data : Vec < RowData > ) -> Rows < ' a > ;
1385
+ fn new_owned ( stmt : Statement < ' a > , data : Vec < RowData > ) -> Rows < ' a > ;
1345
1386
}
1346
1387
1347
1388
trait LazyRowsNew < ' trans , ' stmt > {
1348
1389
fn new ( stmt : & ' stmt Statement < ' stmt > ,
1349
- data : VecDeque < Vec < Option < Vec < u8 > > > > ,
1390
+ data : VecDeque < RowData > ,
1350
1391
name : String ,
1351
1392
row_limit : i32 ,
1352
1393
more_rows : bool ,
0 commit comments