Skip to content

Commit f9b040b

Browse files
committed
Add documentation and improve the implementation of the
`AsyncConnection::test_transaction` function
1 parent 64e6388 commit f9b040b

File tree

1 file changed

+50
-15
lines changed

1 file changed

+50
-15
lines changed

src/lib.rs

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)