@@ -257,28 +257,63 @@ pub trait AsyncConnection: SimpleAsyncConnection + Sized + Send {
257
257
Ok ( ( ) )
258
258
}
259
259
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
262
297
where
263
298
F : for < ' r > FnOnce ( & ' r mut Self ) -> ScopedBoxFuture < ' a , ' r , Result < R , E > > + Send + ' a ,
264
299
E : Debug + Send + ' a ,
265
300
R : Send + ' a ,
266
301
Self : ' a ,
267
302
{
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 ( )
277
314
} )
278
- . await
279
- . expect ( "Test Transaction did not succeed" )
280
- }
281
- . scope_boxed ( )
315
+ . await ;
316
+ user_result. expect ( "Transaction did not succeed" )
282
317
}
283
318
284
319
#[ doc( hidden) ]
0 commit comments