Trait diesel_async::AsyncConnection
source · pub trait AsyncConnection: SimpleAsyncConnection + Sized + Send {
type ExecuteFuture<'conn, 'query>: Future<Output = QueryResult<usize>> + Send
where Self: 'conn;
type LoadFuture<'conn, 'query>: Future<Output = QueryResult<Self::Stream<'conn, 'query>>> + Send
where Self: 'conn;
type Stream<'conn, 'query>: Stream<Item = QueryResult<Self::Row<'conn, 'query>>> + Send
where Self: 'conn;
type Row<'conn, 'query>: Row<'conn, Self::Backend>
where Self: 'conn;
type Backend: Backend;
// Required method
fn establish<'life0, 'async_trait>(
database_url: &'life0 str
) -> Pin<Box<dyn Future<Output = ConnectionResult<Self>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn transaction<'a, 'life0, 'async_trait, R, E, F>(
&'life0 mut self,
callback: F
) -> Pin<Box<dyn Future<Output = Result<R, E>> + Send + 'async_trait>>
where F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait,
E: From<Error> + Send + 'a + 'async_trait,
R: Send + 'a + 'async_trait,
Self: 'async_trait,
'a: 'async_trait,
'life0: 'async_trait { ... }
fn begin_test_transaction<'life0, 'async_trait>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = QueryResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn test_transaction<'a, 'async_trait, R, E, F>(
&'a mut self,
f: F
) -> Pin<Box<dyn Future<Output = R> + Send + 'async_trait>>
where F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait,
E: Debug + Send + 'a + 'async_trait,
R: Send + 'a + 'async_trait,
Self: 'a + 'async_trait,
'a: 'async_trait { ... }
}
Expand description
An async connection to a database
This trait represents a n async database connection. It can be used to query the database through
the query dsl provided by diesel, custom extensions or raw sql queries. It essentially mirrors
the sync diesel Connection
implementation
Required Associated Types§
sourcetype ExecuteFuture<'conn, 'query>: Future<Output = QueryResult<usize>> + Send
where
Self: 'conn
type ExecuteFuture<'conn, 'query>: Future<Output = QueryResult<usize>> + Send where Self: 'conn
The future returned by AsyncConnection::execute
sourcetype LoadFuture<'conn, 'query>: Future<Output = QueryResult<Self::Stream<'conn, 'query>>> + Send
where
Self: 'conn
type LoadFuture<'conn, 'query>: Future<Output = QueryResult<Self::Stream<'conn, 'query>>> + Send where Self: 'conn
The future returned by AsyncConnection::load
sourcetype Stream<'conn, 'query>: Stream<Item = QueryResult<Self::Row<'conn, 'query>>> + Send
where
Self: 'conn
type Stream<'conn, 'query>: Stream<Item = QueryResult<Self::Row<'conn, 'query>>> + Send where Self: 'conn
The inner stream returned by AsyncConnection::load
Required Methods§
sourcefn establish<'life0, 'async_trait>(
database_url: &'life0 str
) -> Pin<Box<dyn Future<Output = ConnectionResult<Self>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn establish<'life0, 'async_trait>( database_url: &'life0 str ) -> Pin<Box<dyn Future<Output = ConnectionResult<Self>> + Send + 'async_trait>>where Self: 'async_trait, 'life0: 'async_trait,
Establishes a new connection to the database
The argument to this method and the method’s behavior varies by backend. See the documentation for that backend’s connection class for details about what it accepts and how it behaves.
Provided Methods§
sourcefn transaction<'a, 'life0, 'async_trait, R, E, F>(
&'life0 mut self,
callback: F
) -> Pin<Box<dyn Future<Output = Result<R, E>> + Send + 'async_trait>>where
F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait,
E: From<Error> + Send + 'a + 'async_trait,
R: Send + 'a + 'async_trait,
Self: 'async_trait,
'a: 'async_trait,
'life0: 'async_trait,
fn transaction<'a, 'life0, 'async_trait, R, E, F>( &'life0 mut self, callback: F ) -> Pin<Box<dyn Future<Output = Result<R, E>> + Send + 'async_trait>>where F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait, E: From<Error> + Send + 'a + 'async_trait, R: Send + 'a + 'async_trait, Self: 'async_trait, 'a: 'async_trait, 'life0: 'async_trait,
Executes the given function inside of a database transaction
This function executes the provided closure f
inside a database
transaction. If there is already an open transaction for the current
connection savepoints will be used instead. The connection is committed if
the closure returns Ok(_)
, it will be rolled back if it returns Err(_)
.
For both cases the original result value will be returned from this function.
If the transaction fails to commit due to a SerializationFailure
or a
ReadOnlyTransaction
a rollback will be attempted.
If the rollback fails, the error will be returned in a
Error::RollbackErrorOnCommit
,
from which you will be able to extract both the original commit error and
the rollback error.
In addition, the connection will be considered broken
as it contains a uncommitted unabortable open transaction. Any further
interaction with the transaction system will result in an returned error
in this case.
If the closure returns an Err(_)
and the rollback fails the function
will return that rollback error directly, and the transaction manager will
be marked as broken as it contains a uncommitted unabortable open transaction.
If a nested transaction fails to release the corresponding savepoint the error will be returned directly.
WARNING: Canceling the returned future does currently not close an already open transaction. You may end up with a connection containing a dangling transaction.
Example
use diesel::result::Error;
use scoped_futures::ScopedFutureExt;
use diesel_async::{RunQueryDsl, AsyncConnection};
conn.transaction::<_, Error, _>(|conn| async move {
diesel::insert_into(users)
.values(name.eq("Ruby"))
.execute(conn)
.await?;
let all_names = users.select(name).load::<String>(conn).await?;
assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names);
Ok(())
}.scope_boxed()).await?;
conn.transaction::<(), _, _>(|conn| async move {
diesel::insert_into(users)
.values(name.eq("Pascal"))
.execute(conn)
.await?;
let all_names = users.select(name).load::<String>(conn).await?;
assert_eq!(vec!["Sean", "Tess", "Ruby", "Pascal"], all_names);
// If we want to roll back the transaction, but don't have an
// actual error to return, we can return `RollbackTransaction`.
Err(Error::RollbackTransaction)
}.scope_boxed()).await;
let all_names = users.select(name).load::<String>(conn).await?;
assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names);
sourcefn begin_test_transaction<'life0, 'async_trait>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = QueryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn begin_test_transaction<'life0, 'async_trait>( &'life0 mut self ) -> Pin<Box<dyn Future<Output = QueryResult<()>> + Send + 'async_trait>>where Self: 'async_trait, 'life0: 'async_trait,
Creates a transaction that will never be committed. This is useful for tests. Panics if called while inside of a transaction or if called with a connection containing a broken transaction
sourcefn test_transaction<'a, 'async_trait, R, E, F>(
&'a mut self,
f: F
) -> Pin<Box<dyn Future<Output = R> + Send + 'async_trait>>where
F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait,
E: Debug + Send + 'a + 'async_trait,
R: Send + 'a + 'async_trait,
Self: 'a + 'async_trait,
'a: 'async_trait,
fn test_transaction<'a, 'async_trait, R, E, F>( &'a mut self, f: F ) -> Pin<Box<dyn Future<Output = R> + Send + 'async_trait>>where F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result<R, E>> + Send + 'a + 'async_trait, E: Debug + Send + 'a + 'async_trait, R: Send + 'a + 'async_trait, Self: 'a + 'async_trait, 'a: 'async_trait,
Executes the given function inside a transaction, but does not commit it. Panics if the given function returns an error.
Example
use diesel::result::Error;
use scoped_futures::ScopedFutureExt;
use diesel_async::{RunQueryDsl, AsyncConnection};
conn.test_transaction::<_, Error, _>(|conn| async move {
diesel::insert_into(users)
.values(name.eq("Ruby"))
.execute(conn)
.await?;
let all_names = users.select(name).load::<String>(conn).await?;
assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names);
Ok(())
}.scope_boxed()).await;
// Even though we returned `Ok`, the transaction wasn't committed.
let all_names = users.select(name).load::<String>(conn).await?;
assert_eq!(vec!["Sean", "Tess"], all_names);
Implementors§
source§impl AsyncConnection for AsyncMysqlConnection
Available on crate feature mysql
only.
impl AsyncConnection for AsyncMysqlConnection
mysql
only.type ExecuteFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'conn, Global>>
type LoadFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<<AsyncMysqlConnection as AsyncConnection>::Stream<'conn, 'query>, Error>> + Send + 'conn, Global>>
type Stream<'conn, 'query> = Pin<Box<dyn Stream<Item = Result<<AsyncMysqlConnection as AsyncConnection>::Row<'conn, 'query>, Error>> + Send + 'conn, Global>>
type Row<'conn, 'query> = MysqlRow
type Backend = Mysql
source§impl AsyncConnection for AsyncPgConnection
Available on crate feature postgres
only.
impl AsyncConnection for AsyncPgConnection
postgres
only.type LoadFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<<AsyncPgConnection as AsyncConnection>::Stream<'conn, 'query>, Error>> + Send + 'query, Global>>
type ExecuteFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'query, Global>>
type Stream<'conn, 'query> = Pin<Box<dyn Stream<Item = Result<PgRow, Error>> + Send, Global>>
type Row<'conn, 'query> = PgRow
type Backend = Pg
source§impl<C> AsyncConnection for Cwhere
C: DerefMut + Send,
C::Target: AsyncConnection,
Available on crate features deadpool
or bb8
or mobc
or r2d2
only.
impl<C> AsyncConnection for Cwhere C: DerefMut + Send, C::Target: AsyncConnection,
deadpool
or bb8
or mobc
or r2d2
only.