File tree Expand file tree Collapse file tree 4 files changed +59
-4
lines changed
Expand file tree Collapse file tree 4 files changed +59
-4
lines changed Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ pub struct OdbcArguments<'q> {
88 pub ( crate ) values : Vec < OdbcArgumentValue < ' q > > ,
99}
1010
11+ #[ derive( Debug , Clone ) ]
1112pub enum OdbcArgumentValue < ' q > {
1213 Text ( String ) ,
1314 Bytes ( Vec < u8 > ) ,
@@ -116,3 +117,40 @@ impl<'q> Encode<'q, Odbc> for Vec<u8> {
116117 crate :: encode:: IsNull :: No
117118 }
118119}
120+
121+ impl < ' q , T > Encode < ' q , Odbc > for Option < T >
122+ where
123+ T : Encode < ' q , Odbc > + Type < Odbc > + ' q ,
124+ {
125+ fn produces ( & self ) -> Option < crate :: odbc:: OdbcTypeInfo > {
126+ if let Some ( v) = self {
127+ v. produces ( )
128+ } else {
129+ T :: type_info ( ) . into ( )
130+ }
131+ }
132+
133+ fn encode ( self , buf : & mut Vec < OdbcArgumentValue < ' q > > ) -> crate :: encode:: IsNull {
134+ match self {
135+ Some ( v) => v. encode ( buf) ,
136+ None => {
137+ buf. push ( OdbcArgumentValue :: Null ) ;
138+ crate :: encode:: IsNull :: Yes
139+ }
140+ }
141+ }
142+
143+ fn encode_by_ref ( & self , buf : & mut Vec < OdbcArgumentValue < ' q > > ) -> crate :: encode:: IsNull {
144+ match self {
145+ Some ( v) => v. encode_by_ref ( buf) ,
146+ None => {
147+ buf. push ( OdbcArgumentValue :: Null ) ;
148+ crate :: encode:: IsNull :: Yes
149+ }
150+ }
151+ }
152+
153+ fn size_hint ( & self ) -> usize {
154+ self . as_ref ( ) . map_or ( 0 , Encode :: size_hint)
155+ }
156+ }
Original file line number Diff line number Diff line change @@ -265,7 +265,7 @@ fn execute_sql_with_params(
265265
266266 let mut params: Vec < Box < dyn odbc_api:: parameter:: InputParameter > > =
267267 Vec :: with_capacity ( args. len ( ) ) ;
268- for a in args {
268+ for a in dbg ! ( args) {
269269 params. push ( to_param ( a) ) ;
270270 }
271271 dispatch_execute ( conn, sql, & params[ ..] , tx) ;
@@ -280,7 +280,7 @@ fn to_param(
280280 OdbcArgumentValue :: Text ( s) => Box :: new ( s. into_parameter ( ) ) ,
281281 OdbcArgumentValue :: Bytes ( b) => Box :: new ( b. into_parameter ( ) ) ,
282282 OdbcArgumentValue :: Null | OdbcArgumentValue :: Phantom ( _) => {
283- Box :: new ( Option :: < i32 > :: None . into_parameter ( ) )
283+ Box :: new ( Option :: < String > :: None . into_parameter ( ) )
284284 }
285285 }
286286}
Original file line number Diff line number Diff line change @@ -47,5 +47,4 @@ impl_column_index_for_statement!(OdbcStatement);
4747impl_acquire ! ( Odbc , OdbcConnection ) ;
4848impl_into_maybe_pool ! ( Odbc , OdbcConnection ) ;
4949
50- // required because some databases have a different handling of NULL
51- impl_encode_for_option ! ( Odbc ) ;
50+ // custom Option<..> handling implemented in `arguments.rs`
Original file line number Diff line number Diff line change @@ -210,3 +210,21 @@ async fn it_can_bind_heterogeneous_params() -> anyhow::Result<()> {
210210 assert_eq ! ( last, 42 ) ;
211211 Ok ( ( ) )
212212}
213+
214+ #[ tokio:: test]
215+ async fn it_binds_null_string_parameter ( ) -> anyhow:: Result < ( ) > {
216+ let mut conn = new :: < Odbc > ( ) . await ?;
217+ let stmt = ( & mut conn) . prepare ( "SELECT ?, ?" ) . await ?;
218+ let row = stmt
219+ . query ( )
220+ . bind ( "abc" )
221+ . bind ( Option :: < String > :: None )
222+ . fetch_one ( & mut conn)
223+ . await ?;
224+
225+ let a = row. try_get_raw ( 0 ) ?. to_owned ( ) . decode :: < String > ( ) ;
226+ let b = row. try_get_raw ( 1 ) ?. to_owned ( ) ;
227+ assert_eq ! ( a, "abc" ) ;
228+ assert ! ( b. is_null( ) ) ;
229+ Ok ( ( ) )
230+ }
You can’t perform that action at this time.
0 commit comments