@@ -32,6 +32,15 @@ fn collect_columns(prepared: &mut PreparedStatement) -> Result<Vec<OdbcColumn>,
3232 Ok ( columns)
3333}
3434
35+ fn collect_statement_metadata (
36+ prepared : & mut PreparedStatement ,
37+ ) -> Result < OdbcStatementMetadata , Error > {
38+ Ok ( OdbcStatementMetadata {
39+ columns : collect_columns ( prepared) ?,
40+ parameters : usize:: from ( prepared. num_params ( ) ?) ,
41+ } )
42+ }
43+
3544pub ( super ) fn describe_column < S > ( stmt : & mut S , index : u16 ) -> Result < OdbcColumn , Error >
3645where
3746 S : ResultSetMetadata ,
@@ -206,15 +215,32 @@ impl OdbcConnection {
206215 }
207216
208217 pub async fn prepare < ' a > ( & mut self , sql : & ' a str ) -> Result < OdbcStatement < ' a > , Error > {
218+ let cached = self
219+ . stmt_cache
220+ . get_mut ( sql)
221+ . map ( |prepared| Arc :: clone ( prepared) ) ;
222+
223+ if let Some ( prepared) = cached {
224+ let metadata = spawn_blocking ( move || {
225+ let mut prepared = prepared. lock ( ) . map_err ( |_| {
226+ Error :: Protocol ( "ODBC prepare: failed to lock prepared statement" . into ( ) )
227+ } ) ?;
228+ collect_statement_metadata ( & mut prepared)
229+ } )
230+ . await ?;
231+
232+ return Ok ( OdbcStatement {
233+ sql : Cow :: Borrowed ( sql) ,
234+ metadata,
235+ } ) ;
236+ }
237+
209238 let conn = Arc :: clone ( & self . conn ) ;
210239 let sql_owned = sql. to_string ( ) ;
211240 let sql_clone = sql_owned. clone ( ) ;
212241 let ( prepared, metadata) = spawn_blocking ( move || {
213242 let mut prepared = conn. into_prepared ( & sql_clone) ?;
214- let metadata = OdbcStatementMetadata {
215- columns : collect_columns ( & mut prepared) ?,
216- parameters : usize:: from ( prepared. num_params ( ) ?) ,
217- } ;
243+ let metadata = collect_statement_metadata ( & mut prepared) ?;
218244 Ok :: < _ , Error > ( ( prepared, metadata) )
219245 } )
220246 . await ?;
0 commit comments