@@ -257,28 +257,63 @@ pub trait AsyncConnection: SimpleAsyncConnection + Sized + Send {
257257 Ok ( ( ) )
258258 }
259259
260- #[ doc( hidden) ]
261- fn test_transaction < ' a , R , E , F > ( & ' a mut self , f : F ) -> ScopedBoxFuture < ' a , ' a , R >
260+ /// Executes the given function inside a transaction, but does not commit
261+ /// it. Panics if the given function returns an error.
262+ ///
263+ /// # Example
264+ ///
265+ /// ```rust
266+ /// # include!("doctest_setup.rs");
267+ /// use diesel::result::Error;
268+ /// use scoped_futures::ScopedFutureExt;
269+ ///
270+ /// # #[tokio::main(flavor = "current_thread")]
271+ /// # async fn main() {
272+ /// # run_test().await.unwrap();
273+ /// # }
274+ /// #
275+ /// # async fn run_test() -> QueryResult<()> {
276+ /// # use schema::users::dsl::*;
277+ /// # let conn = &mut establish_connection().await;
278+ /// conn.test_transaction::<_, Error, _>(|conn| async move {
279+ /// diesel::insert_into(users)
280+ /// .values(name.eq("Ruby"))
281+ /// .execute(conn)
282+ /// .await?;
283+ ///
284+ /// let all_names = users.select(name).load::<String>(conn).await?;
285+ /// assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names);
286+ ///
287+ /// Ok(())
288+ /// }.scope_boxed()).await;
289+ ///
290+ /// // Even though we returned `Ok`, the transaction wasn't committed.
291+ /// let all_names = users.select(name).load::<String>(conn).await?;
292+ /// assert_eq!(vec!["Sean", "Tess"], all_names);
293+ /// # Ok(())
294+ /// # }
295+ /// ```
296+ async fn test_transaction < ' a , R , E , F > ( & ' a mut self , f : F ) -> R
262297 where
263298 F : for < ' r > FnOnce ( & ' r mut Self ) -> ScopedBoxFuture < ' a , ' r , Result < R , E > > + Send + ' a ,
264299 E : Debug + Send + ' a ,
265300 R : Send + ' a ,
266301 Self : ' a ,
267302 {
268- async move {
269- self . transaction :: < R , _ , _ > ( |c| {
270- async move {
271- match f ( c) . await {
272- Ok ( t) => Ok ( t) ,
273- Err ( _) => Err ( Error :: RollbackTransaction ) ,
274- }
275- }
276- . scope_boxed ( )
303+ use futures_util:: TryFutureExt ;
304+
305+ let mut user_result = None ;
306+ let _ = self
307+ . transaction :: < R , _ , _ > ( |c| {
308+ f ( c) . map_err ( |_| Error :: RollbackTransaction )
309+ . and_then ( |r| {
310+ user_result = Some ( r) ;
311+ futures_util:: future:: ready ( Err ( Error :: RollbackTransaction ) )
312+ } )
313+ . scope_boxed ( )
277314 } )
278- . await
279- . expect ( "Test Transaction did not succeed" )
280- }
281- . scope_boxed ( )
315+ . await ;
316+ user_result. expect ( "Transaction did not succeed" )
282317 }
283318
284319 #[ doc( hidden) ]
0 commit comments