@@ -11,11 +11,23 @@ use crate::mysql::types::MYSQL_TIME;
1111use crate :: mysql:: { MysqlType , MysqlValue } ;
1212use crate :: result:: QueryResult ;
1313
14- pub struct Binds {
14+ pub struct PreparedStatementBinds ( Binds ) ;
15+
16+ pub struct OutputBinds ( Binds ) ;
17+
18+ impl Clone for OutputBinds {
19+ fn clone ( & self ) -> Self {
20+ Self ( Binds {
21+ data : self . 0 . data . clone ( ) ,
22+ } )
23+ }
24+ }
25+
26+ struct Binds {
1527 data : Vec < BindData > ,
1628}
1729
18- impl Binds {
30+ impl PreparedStatementBinds {
1931 pub fn from_input_data < Iter > ( input : Iter ) -> QueryResult < Self >
2032 where
2133 Iter : IntoIterator < Item = ( MysqlType , Option < Vec < u8 > > ) > ,
@@ -25,34 +37,31 @@ impl Binds {
2537 . map ( BindData :: for_input)
2638 . collect :: < Vec < _ > > ( ) ;
2739
28- Ok ( Binds { data } )
40+ Ok ( Self ( Binds { data } ) )
2941 }
3042
31- pub fn from_output_types ( types : Vec < Option < MysqlType > > , metadata : & StatementMetadata ) -> Self {
43+ pub fn with_mysql_binds < F , T > ( & mut self , f : F ) -> T
44+ where
45+ F : FnOnce ( * mut ffi:: MYSQL_BIND ) -> T ,
46+ {
47+ self . 0 . with_mysql_binds ( f)
48+ }
49+ }
50+
51+ impl OutputBinds {
52+ pub fn from_output_types ( types : & [ Option < MysqlType > ] , metadata : & StatementMetadata ) -> Self {
3253 let data = metadata
3354 . fields ( )
3455 . iter ( )
35- . zip ( types. into_iter ( ) . chain ( std:: iter:: repeat ( None ) ) )
56+ . zip ( types. iter ( ) . copied ( ) . chain ( std:: iter:: repeat ( None ) ) )
3657 . map ( |( field, tpe) | BindData :: for_output ( tpe, field) )
3758 . collect ( ) ;
3859
39- Binds { data }
40- }
41-
42- pub fn with_mysql_binds < F , T > ( & mut self , f : F ) -> T
43- where
44- F : FnOnce ( * mut ffi:: MYSQL_BIND ) -> T ,
45- {
46- let mut binds = self
47- . data
48- . iter_mut ( )
49- . map ( |x| unsafe { x. mysql_bind ( ) } )
50- . collect :: < Vec < _ > > ( ) ;
51- f ( binds. as_mut_ptr ( ) )
60+ Self ( Binds { data } )
5261 }
5362
5463 pub fn populate_dynamic_buffers ( & mut self , stmt : & Statement ) -> QueryResult < ( ) > {
55- for ( i, data) in self . data . iter_mut ( ) . enumerate ( ) {
64+ for ( i, data) in self . 0 . data . iter_mut ( ) . enumerate ( ) {
5665 data. did_numeric_overflow_occur ( ) ?;
5766 // This is safe because we are re-binding the invalidated buffers
5867 // at the end of this function
@@ -69,20 +78,37 @@ impl Binds {
6978 }
7079
7180 pub fn update_buffer_lengths ( & mut self ) {
72- for data in & mut self . data {
81+ for data in & mut self . 0 . data {
7382 data. update_buffer_length ( ) ;
7483 }
7584 }
7685
77- pub fn len ( & self ) -> usize {
78- self . data . len ( )
86+ pub fn with_mysql_binds < F , T > ( & mut self , f : F ) -> T
87+ where
88+ F : FnOnce ( * mut ffi:: MYSQL_BIND ) -> T ,
89+ {
90+ self . 0 . with_mysql_binds ( f)
91+ }
92+ }
93+
94+ impl Binds {
95+ fn with_mysql_binds < F , T > ( & mut self , f : F ) -> T
96+ where
97+ F : FnOnce ( * mut ffi:: MYSQL_BIND ) -> T ,
98+ {
99+ let mut binds = self
100+ . data
101+ . iter_mut ( )
102+ . map ( |x| unsafe { x. mysql_bind ( ) } )
103+ . collect :: < Vec < _ > > ( ) ;
104+ f ( binds. as_mut_ptr ( ) )
79105 }
80106}
81107
82- impl Index < usize > for Binds {
108+ impl Index < usize > for OutputBinds {
83109 type Output = BindData ;
84110 fn index ( & self , index : usize ) -> & Self :: Output {
85- & self . data [ index]
111+ & self . 0 . data [ index]
86112 }
87113}
88114
@@ -122,7 +148,7 @@ impl From<u32> for Flags {
122148 }
123149}
124150
125- #[ derive( Debug ) ]
151+ #[ derive( Debug , Clone ) ]
126152pub struct BindData {
127153 tpe : ffi:: enum_field_types ,
128154 bytes : Vec < u8 > ,
@@ -713,9 +739,8 @@ mod tests {
713739 )
714740 . unwrap ( ) ;
715741
716- let mut stmt = conn
717- . prepare_query ( & crate :: sql_query (
718- "SELECT
742+ let mut stmt = conn. prepared_query ( & crate :: sql_query (
743+ "SELECT
719744 tiny_int, small_int, medium_int, int_col,
720745 big_int, unsigned_int, zero_fill_int,
721746 numeric_col, decimal_col, float_col, double_col, bit_col,
@@ -725,30 +750,21 @@ mod tests {
725750 ST_AsText(polygon_col), ST_AsText(multipoint_col), ST_AsText(multilinestring_col),
726751 ST_AsText(multipolygon_col), ST_AsText(geometry_collection), json_col
727752 FROM all_mysql_types" ,
728- ) )
729- . unwrap ( ) ;
753+ ) ) . unwrap ( ) ;
730754
731755 let metadata = stmt. metadata ( ) . unwrap ( ) ;
732756 let mut output_binds =
733- Binds :: from_output_types ( vec ! [ None ; metadata. fields( ) . len( ) ] , & metadata) ;
757+ OutputBinds :: from_output_types ( & vec ! [ None ; metadata. fields( ) . len( ) ] , & metadata) ;
734758 stmt. execute_statement ( & mut output_binds) . unwrap ( ) ;
735759 stmt. populate_row_buffers ( & mut output_binds) . unwrap ( ) ;
736760
737761 let results: Vec < ( BindData , & _ ) > = output_binds
762+ . 0
738763 . data
739764 . into_iter ( )
740765 . zip ( metadata. fields ( ) )
741766 . collect :: < Vec < _ > > ( ) ;
742767
743- macro_rules! matches {
744- ( $expression: expr, $( $pattern: pat ) |+ $( if $guard: expr ) ?) => {
745- match $expression {
746- $( $pattern ) |+ $( if $guard ) ? => true ,
747- _ => false
748- }
749- }
750- }
751-
752768 let tiny_int_col = & results[ 0 ] . 0 ;
753769 assert_eq ! ( tiny_int_col. tpe, ffi:: enum_field_types:: MYSQL_TYPE_TINY ) ;
754770 assert ! ( tiny_int_col. flags. contains( Flags :: NUM_FLAG ) ) ;
@@ -1057,9 +1073,9 @@ mod tests {
10571073 assert ! ( !polygon_col. flags. contains( Flags :: ENUM_FLAG ) ) ;
10581074 assert ! ( !polygon_col. flags. contains( Flags :: BINARY_FLAG ) ) ;
10591075 assert_eq ! (
1060- to_value:: <Text , String >( polygon_col) . unwrap( ) ,
1061- "MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))"
1062- ) ;
1076+ to_value:: <Text , String >( polygon_col) . unwrap( ) ,
1077+ "MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))"
1078+ ) ;
10631079
10641080 let geometry_collection = & results[ 32 ] . 0 ;
10651081 assert_eq ! (
@@ -1105,12 +1121,12 @@ mod tests {
11051121
11061122 let bind = BindData :: for_test_output ( bind_tpe. into ( ) ) ;
11071123
1108- let mut binds = Binds { data : vec ! [ bind] } ;
1124+ let mut binds = OutputBinds ( Binds { data : vec ! [ bind] } ) ;
11091125
11101126 stmt. execute_statement ( & mut binds) . unwrap ( ) ;
11111127 stmt. populate_row_buffers ( & mut binds) . unwrap ( ) ;
11121128
1113- binds. data . remove ( 0 )
1129+ binds. 0 . data . remove ( 0 )
11141130 }
11151131
11161132 fn input_bind (
@@ -1144,9 +1160,9 @@ mod tests {
11441160 is_truncated : None ,
11451161 } ;
11461162
1147- let binds = Binds {
1163+ let binds = PreparedStatementBinds ( Binds {
11481164 data : vec ! [ id_bind, field_bind] ,
1149- } ;
1165+ } ) ;
11501166 stmt. input_bind ( binds) . unwrap ( ) ;
11511167 stmt. did_an_error_occur ( ) . unwrap ( ) ;
11521168 unsafe {
0 commit comments