diesel_async

Trait AsyncConnection

Source
pub trait AsyncConnection:
    SimpleAsyncConnection
    + Sized
    + Send {
    type ExecuteFuture<'conn, 'query>: Future<Output = QueryResult<usize>> + Send;
    type LoadFuture<'conn, 'query>: Future<Output = QueryResult<Self::Stream<'conn, 'query>>> + Send;
    type Stream<'conn, 'query>: Stream<Item = QueryResult<Self::Row<'conn, 'query>>> + Send;
    type Row<'conn, 'query>: Row<'conn, Self::Backend>;
    type Backend: Backend;

    // Required methods
    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;
    fn set_instrumentation(&mut self, instrumentation: impl Instrumentation);

    // 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§

Source

type ExecuteFuture<'conn, 'query>: Future<Output = QueryResult<usize>> + Send

The future returned by AsyncConnection::execute

Source

type LoadFuture<'conn, 'query>: Future<Output = QueryResult<Self::Stream<'conn, 'query>>> + Send

The future returned by AsyncConnection::load

Source

type Stream<'conn, 'query>: Stream<Item = QueryResult<Self::Row<'conn, 'query>>> + Send

The inner stream returned by AsyncConnection::load

Source

type Row<'conn, 'query>: Row<'conn, Self::Backend>

The row type used by the stream returned by AsyncConnection::load

Source

type Backend: Backend

The backend this type connects to

Required Methods§

Source

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.

Source

fn set_instrumentation(&mut self, instrumentation: impl Instrumentation)

Set a specific Instrumentation implementation for this connection

Provided Methods§

Source

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);
Source

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

Source

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);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl AsyncConnection for AsyncMysqlConnection

Available on crate feature mysql only.
Source§

type ExecuteFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'conn>>

Source§

type LoadFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<<AsyncMysqlConnection as AsyncConnection>::Stream<'conn, 'query>, Error>> + Send + 'conn>>

Source§

type Stream<'conn, 'query> = Pin<Box<dyn Stream<Item = Result<<AsyncMysqlConnection as AsyncConnection>::Row<'conn, 'query>, Error>> + Send + 'conn>>

Source§

type Row<'conn, 'query> = MysqlRow

Source§

type Backend = Mysql

Source§

impl AsyncConnection for AsyncPgConnection

Available on crate feature postgres only.
Source§

type LoadFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<<AsyncPgConnection as AsyncConnection>::Stream<'conn, 'query>, Error>> + Send + 'query>>

Source§

type ExecuteFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'query>>

Source§

type Stream<'conn, 'query> = Pin<Box<dyn Stream<Item = Result<PgRow, Error>> + Send>>

Source§

type Row<'conn, 'query> = PgRow

Source§

type Backend = Pg

Source§

impl<C> AsyncConnection for C

Available on crate feature pool only.
Source§

type ExecuteFuture<'conn, 'query> = <<C as Deref>::Target as AsyncConnection>::ExecuteFuture<'conn, 'query>

Source§

type LoadFuture<'conn, 'query> = <<C as Deref>::Target as AsyncConnection>::LoadFuture<'conn, 'query>

Source§

type Stream<'conn, 'query> = <<C as Deref>::Target as AsyncConnection>::Stream<'conn, 'query>

Source§

type Row<'conn, 'query> = <<C as Deref>::Target as AsyncConnection>::Row<'conn, 'query>

Source§

type Backend = <<C as Deref>::Target as AsyncConnection>::Backend

Source§

impl<C, MD, O> AsyncConnection for SyncConnectionWrapper<C>
where <C as Connection>::Backend: Default + DieselReserveSpecialization, <C::Backend as Backend>::QueryBuilder: Default, C: Connection + LoadConnection + WithMetadataLookup + 'static, <C as Connection>::TransactionManager: Send, MD: Send + 'static, for<'a> <C::Backend as Backend>::BindCollector<'a>: MoveableBindCollector<C::Backend, BindData = MD> + Default, O: 'static + Send + for<'conn> Row<'conn, C::Backend>, for<'conn, 'query> <C as LoadConnection>::Row<'conn, 'query>: IntoOwnedRow<'conn, <C as Connection>::Backend, OwnedRow = O>,

Available on crate feature sync-connection-wrapper only.
Source§

type LoadFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<<SyncConnectionWrapper<C> as AsyncConnection>::Stream<'conn, 'query>, Error>> + Send + 'query>>

Source§

type ExecuteFuture<'conn, 'query> = Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'query>>

Source§

type Stream<'conn, 'query> = Pin<Box<dyn Stream<Item = Result<<SyncConnectionWrapper<C> as AsyncConnection>::Row<'conn, 'query>, Error>> + Send>>

Source§

type Row<'conn, 'query> = O

Source§

type Backend = <C as Connection>::Backend