1- use crate :: stmt_cache:: { PrepareCallback , StmtCache } ;
1+ use crate :: stmt_cache:: { CallbackHelper , QueryFragmentHelper } ;
22use crate :: { AnsiTransactionManager , AsyncConnection , SimpleAsyncConnection } ;
3- use diesel:: connection:: statement_cache:: { MaybeCached , StatementCacheKey } ;
4- use diesel :: connection :: Instrumentation ;
5- use diesel :: connection :: InstrumentationEvent ;
3+ use diesel:: connection:: statement_cache:: {
4+ MaybeCached , QueryFragmentForCachedStatement , StatementCache ,
5+ } ;
66use diesel:: connection:: StrQueryHelper ;
7+ use diesel:: connection:: { CacheSize , Instrumentation } ;
8+ use diesel:: connection:: { DynInstrumentation , InstrumentationEvent } ;
79use diesel:: mysql:: { Mysql , MysqlQueryBuilder , MysqlType } ;
810use diesel:: query_builder:: QueryBuilder ;
911use diesel:: query_builder:: { bind_collector:: RawBytesBindCollector , QueryFragment , QueryId } ;
@@ -27,9 +29,9 @@ use self::serialize::ToSqlHelper;
2729/// `mysql://[user[:password]@]host/database_name`
2830pub struct AsyncMysqlConnection {
2931 conn : mysql_async:: Conn ,
30- stmt_cache : StmtCache < Mysql , Statement > ,
32+ stmt_cache : StatementCache < Mysql , Statement > ,
3133 transaction_manager : AnsiTransactionManager ,
32- instrumentation : std :: sync :: Mutex < Option < Box < dyn Instrumentation > > > ,
34+ instrumentation : DynInstrumentation ,
3335}
3436
3537#[ async_trait:: async_trait]
@@ -72,7 +74,7 @@ impl AsyncConnection for AsyncMysqlConnection {
7274 type TransactionManager = AnsiTransactionManager ;
7375
7476 async fn establish ( database_url : & str ) -> diesel:: ConnectionResult < Self > {
75- let mut instrumentation = diesel :: connection :: get_default_instrumentation ( ) ;
77+ let mut instrumentation = DynInstrumentation :: default_instrumentation ( ) ;
7678 instrumentation. on_connection_event ( InstrumentationEvent :: start_establish_connection (
7779 database_url,
7880 ) ) ;
@@ -82,7 +84,7 @@ impl AsyncConnection for AsyncMysqlConnection {
8284 r. as_ref ( ) . err ( ) ,
8385 ) ) ;
8486 let mut conn = r?;
85- conn. instrumentation = std :: sync :: Mutex :: new ( instrumentation) ;
87+ conn. instrumentation = instrumentation;
8688 Ok ( conn)
8789 }
8890
@@ -177,16 +179,15 @@ impl AsyncConnection for AsyncMysqlConnection {
177179 }
178180
179181 fn instrumentation ( & mut self ) -> & mut dyn Instrumentation {
180- self . instrumentation
181- . get_mut ( )
182- . unwrap_or_else ( |p| p. into_inner ( ) )
182+ & mut * self . instrumentation
183183 }
184184
185185 fn set_instrumentation ( & mut self , instrumentation : impl Instrumentation ) {
186- * self
187- . instrumentation
188- . get_mut ( )
189- . unwrap_or_else ( |p| p. into_inner ( ) ) = Some ( Box :: new ( instrumentation) ) ;
186+ self . instrumentation = instrumentation. into ( ) ;
187+ }
188+
189+ fn set_prepared_statement_cache_size ( & mut self , size : CacheSize ) {
190+ self . stmt_cache . set_cache_size ( size) ;
190191 }
191192}
192193
@@ -207,17 +208,24 @@ fn update_transaction_manager_status<T>(
207208 query_result
208209}
209210
210- #[ async_trait:: async_trait]
211- impl PrepareCallback < Statement , MysqlType > for & ' _ mut mysql_async:: Conn {
212- async fn prepare (
213- self ,
214- sql : & str ,
215- _metadata : & [ MysqlType ] ,
216- _is_for_cache : diesel:: connection:: statement_cache:: PrepareForCache ,
217- ) -> QueryResult < ( Statement , Self ) > {
218- let s = self . prep ( sql) . await . map_err ( ErrorHelper ) ?;
219- Ok ( ( s, self ) )
220- }
211+ fn prepare_statement_helper < ' a , ' b > (
212+ conn : & ' a mut mysql_async:: Conn ,
213+ sql : & ' b str ,
214+ _is_for_cache : diesel:: connection:: statement_cache:: PrepareForCache ,
215+ _metadata : & [ MysqlType ] ,
216+ ) -> CallbackHelper < impl Future < Output = QueryResult < ( Statement , & ' a mut mysql_async:: Conn ) > > + Send >
217+ {
218+ // ideally we wouldn't clone the SQL string here
219+ // but as we usually cache statements anyway
220+ // this is a fixed one time const
221+ //
222+ // The probleme with not cloning it is that we then cannot express
223+ // the right result lifetime anymore (at least not easily)
224+ let sql = sql. to_owned ( ) ;
225+ CallbackHelper ( async move {
226+ let s = conn. prep ( sql) . await . map_err ( ErrorHelper ) ?;
227+ Ok ( ( s, conn) )
228+ } )
221229}
222230
223231impl AsyncMysqlConnection {
@@ -229,11 +237,9 @@ impl AsyncMysqlConnection {
229237 use crate :: run_query_dsl:: RunQueryDsl ;
230238 let mut conn = AsyncMysqlConnection {
231239 conn,
232- stmt_cache : StmtCache :: new ( ) ,
240+ stmt_cache : StatementCache :: new ( ) ,
233241 transaction_manager : AnsiTransactionManager :: default ( ) ,
234- instrumentation : std:: sync:: Mutex :: new (
235- diesel:: connection:: get_default_instrumentation ( ) ,
236- ) ,
242+ instrumentation : DynInstrumentation :: default_instrumentation ( ) ,
237243 } ;
238244
239245 for stmt in CONNECTION_SETUP_QUERIES {
@@ -286,36 +292,29 @@ impl AsyncMysqlConnection {
286292 } = bind_collector?;
287293 let is_safe_to_cache_prepared = is_safe_to_cache_prepared?;
288294 let sql = sql?;
295+ let helper = QueryFragmentHelper {
296+ sql,
297+ safe_to_cache : is_safe_to_cache_prepared,
298+ } ;
289299 let inner = async {
290- let cache_key = if let Some ( query_id) = query_id {
291- StatementCacheKey :: Type ( query_id)
292- } else {
293- StatementCacheKey :: Sql {
294- sql : sql. clone ( ) ,
295- bind_types : metadata. clone ( ) ,
296- }
297- } ;
298-
299300 let ( stmt, conn) = stmt_cache
300- . cached_prepared_statement (
301- cache_key ,
302- sql . clone ( ) ,
303- is_safe_to_cache_prepared ,
301+ . cached_statement_non_generic (
302+ query_id ,
303+ & helper ,
304+ & Mysql ,
304305 & metadata,
305306 conn,
306- instrumentation,
307+ prepare_statement_helper,
308+ & mut * * instrumentation,
307309 )
308310 . await ?;
309311 callback ( conn, stmt, ToSqlHelper { metadata, binds } ) . await
310312 } ;
311313 let r = update_transaction_manager_status ( inner. await , transaction_manager) ;
312- instrumentation
313- . get_mut ( )
314- . unwrap_or_else ( |p| p. into_inner ( ) )
315- . on_connection_event ( InstrumentationEvent :: finish_query (
316- & StrQueryHelper :: new ( & sql) ,
317- r. as_ref ( ) . err ( ) ,
318- ) ) ;
314+ instrumentation. on_connection_event ( InstrumentationEvent :: finish_query (
315+ & StrQueryHelper :: new ( & helper. sql ) ,
316+ r. as_ref ( ) . err ( ) ,
317+ ) ) ;
319318 r
320319 }
321320 . boxed ( )
@@ -370,9 +369,9 @@ impl AsyncMysqlConnection {
370369
371370 Ok ( AsyncMysqlConnection {
372371 conn,
373- stmt_cache : StmtCache :: new ( ) ,
372+ stmt_cache : StatementCache :: new ( ) ,
374373 transaction_manager : AnsiTransactionManager :: default ( ) ,
375- instrumentation : std :: sync :: Mutex :: new ( None ) ,
374+ instrumentation : DynInstrumentation :: none ( ) ,
376375 } )
377376 }
378377}
@@ -427,3 +426,13 @@ mod tests {
427426 }
428427 }
429428}
429+
430+ impl QueryFragmentForCachedStatement < Mysql > for QueryFragmentHelper {
431+ fn construct_sql ( & self , _backend : & Mysql ) -> QueryResult < String > {
432+ Ok ( self . sql . clone ( ) )
433+ }
434+
435+ fn is_safe_to_cache_prepared ( & self , _backend : & Mysql ) -> QueryResult < bool > {
436+ Ok ( self . safe_to_cache )
437+ }
438+ }
0 commit comments