@@ -5,6 +5,67 @@ use crate::transaction::Transaction;
5
5
use futures_core:: future:: BoxFuture ;
6
6
use std:: ops:: { Deref , DerefMut } ;
7
7
8
+ /// Acquire connections or transactions from a database in a generic way.
9
+ ///
10
+ /// If you want to accept generic database connections that implement
11
+ /// [`Acquire`] which then allows you to [`acquire`][`Acquire::acquire`] a
12
+ /// connection or [`begin`][`Acquire::begin`] a transaction, then you can do it
13
+ /// like that:
14
+ ///
15
+ /// ```rust
16
+ /// # use sqlx::{Acquire, postgres::Postgres, error::BoxDynError};
17
+ /// async fn run_query<'a, A>(conn: A) -> Result<(), BoxDynError>
18
+ /// where
19
+ /// A: Acquire<'a, Database = Postgres>,
20
+ /// {
21
+ /// let mut conn = conn.acquire().await?;
22
+ ///
23
+ /// sqlx::query!("SELECT 1 as v").fetch_one(&mut *conn).await?;
24
+ /// sqlx::query!("SELECT 2 as v").fetch_one(&mut *conn).await?;
25
+ ///
26
+ /// Ok(())
27
+ /// }
28
+ /// ```
29
+ ///
30
+ /// If you run into a lifetime error about "implementation of `sqlx::Acquire` is
31
+ /// not general enough", the [workaround] looks like this:
32
+ ///
33
+ /// ```rust
34
+ /// # use std::future::Future;
35
+ /// # use sqlx::{Acquire, postgres::Postgres, error::BoxDynError};
36
+ /// fn run_query<'a, 'c, A>(conn: A) -> impl Future<Output = Result<(), BoxDynError>> + Send + 'a
37
+ /// where
38
+ /// A: Acquire<'c, Database = Postgres> + Send + 'a,
39
+ /// {
40
+ /// async move {
41
+ /// let mut conn = conn.acquire().await?;
42
+ ///
43
+ /// sqlx::query!("SELECT 1 as v").fetch_one(&mut *conn).await?;
44
+ /// sqlx::query!("SELECT 2 as v").fetch_one(&mut *conn).await?;
45
+ ///
46
+ /// Ok(())
47
+ /// }
48
+ /// }
49
+ /// ```
50
+ ///
51
+ /// However, if you really just want to accept both, a transaction or a
52
+ /// connection as an argument to a function, then it's easier to just accept a
53
+ /// mutable reference to a database connection like so:
54
+ ///
55
+ /// ```rust
56
+ /// # use sqlx::{postgres::PgConnection, error::BoxDynError};
57
+ /// async fn run_query(conn: &mut PgConnection) -> Result<(), BoxDynError> {
58
+ /// sqlx::query!("SELECT 1 as v").fetch_one(&mut *conn).await?;
59
+ /// sqlx::query!("SELECT 2 as v").fetch_one(&mut *conn).await?;
60
+ ///
61
+ /// Ok(())
62
+ /// }
63
+ /// ```
64
+ ///
65
+ /// The downside of this approach is that you have to `acquire` a connection
66
+ /// from a pool first and can't directly pass the pool as argument.
67
+ ///
68
+ /// [workaround]: https://github.com/launchbadge/sqlx/issues/1015#issuecomment-767787777
8
69
pub trait Acquire < ' c > {
9
70
type Database : Database ;
10
71
0 commit comments