# A async interface for diesel
Diesel gets rid of the boilerplate for database interaction and eliminates
runtime errors without sacrificing performance. It takes full advantage of
Rust's type system to create a low overhead query builder that "feels like
Rust."
Diesel-async provides an async implementation of diesels connection implementation
and any method that may issue an query. It is designed as pure async drop-in replacement
for the corresponding diesel methods. Similar to diesel the crate is designed in a way
that allows third party crates to extend the existing infrastructure and even provide
their own connection implementations.
Supported databases:
1. PostgreSQL
2. MySQL
## Usage
### Simple usage
Diesel-async is designed to work in combination with diesel, not to replace diesel. For this it
provides drop-in replacement for diesel functionality that actually interacts with the database.
A normal project should use a setup similar to the following one:
```toml
[dependencies]
diesel = "2.1.0" # no backend features need to be enabled
diesel-async = { version = "0.3.1", features = ["postgres"] }
```
This allows to import the relevant traits from both crates:
```rust
use diesel::prelude::*;
use diesel_async::{RunQueryDsl, AsyncConnection, AsyncPgConnection};
// ordinary diesel model setup
table! {
users {
id -> Integer,
name -> Text,
}
}
#[derive(Queryable, Selectable)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
}
// create an async connection
let mut connection = AsyncPgConnection::establish(&std::env::var("DATABASE_URL")?).await?;
// use ordinary diesel query dsl to construct your query
let data: Vec<User> = users::table
.filter(users::id.gt(0))
.or_filter(users::name.like("%Luke"))
.select(User::as_select())
// execute the query via the provided
// async `diesel_async::RunQueryDsl`
.load(&mut connection)
.await?;
```
### Async Transaction Support
Diesel-async provides an ergonomic interface to wrap several statements into a shared
database transaction. Such transactions are automatically rolled back as soon as
the inner closure returns an error
``` rust
Ok(())
}.scope_boxed()
).await?;
```
### Streaming Query Support
Beside loading data directly into a vector, diesel-async also supports returning a
value stream for each query. This allows to process data from the database while they
are still received.
```rust
// use ordinary diesel query dsl to construct your query
let data: impl Stream<Item = QueryResult<User>> = users::table
.filter(users::id.gt(0))
.or_filter(users::name.like("%Luke"))
.select(User::as_select())
// execute the query via the provided
// async `diesel_async::RunQueryDsl`
.load_stream(&mut connection)
.await?;
```
### Built-in Connection Pooling Support
Diesel-async provides built-in support for several connection pooling crates. This includes support
for:
* [deadpool](https://crates.io/crates/deadpool)
* [bb8](https://crates.io/crates/bb8)
* [mobc](https://crates.io/crates/mobc)
#### Deadpool
``` rust
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
use diesel_async::pooled_connection::deadpool::Pool;
use diesel_async::RunQueryDsl;
// create a new connection pool with the default config
let config = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new(std::env::var("DATABASE_URL")?);
let pool = Pool::builder(config).build()?;
// checkout a connection from the pool
let mut conn = pool.get().await?;
// use the connection as ordinary diesel-async connection
let res = users::table.select(User::as_select()).load::(&mut conn).await?;
```
#### BB8
``` rust
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
use diesel_async::pooled_connection::bb8::Pool;
use diesel_async::RunQueryDsl;
// create a new connection pool with the default config
let config = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new(std::env::var("DATABASE_URL")?);
let pool = Pool::builder().build(config).await?;
// checkout a connection from the pool
let mut conn = pool.get().await?;
// use the connection as ordinary diesel-async connection
let res = users::table.select(User::as_select()).load::(&mut conn).await?;
```
#### Mobc
``` rust
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
use diesel_async::pooled_connection::mobc::Pool;
use diesel_async::RunQueryDsl;
// create a new connection pool with the default config
let config = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new(std::env::var("DATABASE_URL")?);
let pool = Pool::new(config);
// checkout a connection from the pool
let mut conn = pool.get().await?;
// use the connection as ordinary diesel-async connection
let res = users::table.select(User::as_select()).load::(&mut conn).await?;
```
## Crate Feature Flags
Diesel-async offers several configurable features:
* `postgres`: Enables the implementation of `AsyncPgConnection`
* `mysql`: Enables the implementation of `AsyncMysqlConnection`
* `deadpool`: Enables support for the `deadpool` connection pool implementation
* `bb8`: Enables support for the `bb8` connection pool implementation
* `mobc`: Enables support for the `mobc` connection pool implementation
By default no features are enabled.
## Code of conduct
Anyone who interacts with Diesel in any space, including but not limited to
this GitHub repository, must follow our [code of conduct](https://github.com/diesel-rs/diesel/blob/master/code_of_conduct.md).
## License
Licensed under either of these:
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
https://opensource.org/licenses/MIT)
### Contributing
Contributions are explicitly welcome. Please consider opening a [discussion](https://github.com/weiznich/diesel_async/discussions/categories/ideas)
with your idea first, to discuss possible designs.
Unless you explicitly state otherwise, any contribution you intentionally submit
for inclusion in the work, as defined in the Apache-2.0 license, shall be
dual-licensed as above, without any additional terms or conditions.