rocket_db_pools/
lib.rs

1//! Asynchronous database driver connection pooling integration for Rocket.
2//!
3//! # Quickstart
4//!
5//! 1. Add `rocket_db_pools` as a dependency with one or more [database driver
6//!    features](#supported-drivers) enabled:
7//!
8//!    ```toml
9//!    [dependencies.rocket_db_pools]
10//!    version = "0.1.0"
11//!    features = ["sqlx_sqlite"]
12//!    ```
13//!
14//! 2. Choose a name for your database, here `sqlite_logs`.
15//!    [Configure](#configuration) _at least_ a URL for the database:
16//!
17//!    ```toml
18//!    [default.databases.sqlite_logs]
19//!    url = "/path/to/database.sqlite"
20//!    ```
21//!
22//! 3. [Derive](derive@Database) [`Database`] for a unit type (`Logs` here)
23//!    which wraps the selected driver's [`Pool`] type (see [the driver
24//!    table](#supported-drivers)) and is decorated with `#[database("name")]`.
25//!    Attach `Type::init()` to your application's `Rocket` to initialize the
26//!    database pool:
27//!
28//!    ```rust
29//!    # #[cfg(feature = "sqlx_sqlite")] mod _inner {
30//!    # use rocket::launch;
31//!    use rocket_db_pools::{sqlx, Database};
32//!
33//!    #[derive(Database)]
34//!    #[database("sqlite_logs")]
35//!    struct Logs(sqlx::SqlitePool);
36//!
37//!    #[launch]
38//!    fn rocket() -> _ {
39//!        rocket::build().attach(Logs::init())
40//!    }
41//!    # }
42//!    ```
43//!
44//! 4. Use [`Connection<Type>`](Connection) as a request guard to retrieve an
45//!    active database connection, which dereferences to the native type in the
46//!    [`Connection` deref](#supported-drivers) column.
47//!
48//!    ```rust
49//!    # #[cfg(feature = "sqlx_sqlite")] mod _inner {
50//!    # use rocket::{get, response::Responder};
51//!    # use rocket_db_pools::{sqlx, Database};
52//!    # #[derive(Database)]
53//!    # #[database("sqlite_logs")]
54//!    # struct Logs(sqlx::SqlitePool);
55//!    #
56//!    # #[derive(Responder)]
57//!    # struct Log(String);
58//!    #
59//!    use rocket_db_pools::Connection;
60//!    use rocket_db_pools::sqlx::Row;
61//!
62//!    #[get("/<id>")]
63//!    async fn read(mut db: Connection<Logs>, id: i64) -> Option<Log> {
64//!        sqlx::query("SELECT content FROM logs WHERE id = ?").bind(id)
65//!            .fetch_one(&mut **db).await
66//!            .and_then(|r| Ok(Log(r.try_get(0)?)))
67//!            .ok()
68//!    }
69//!    # }
70//!    ```
71//!
72//!    Alternatively, use a reference to the database type as a request guard to
73//!    retrieve the entire pool, but note that unlike retrieving a `Connection`,
74//!    doing so does _not_ guarantee that a connection is available:
75//!
76//!    ```rust
77//!    # #[cfg(feature = "sqlx_sqlite")] mod _inner {
78//!    # use rocket::{get, response::Responder};
79//!    # use rocket_db_pools::{sqlx, Database};
80//!    # #[derive(Database)]
81//!    # #[database("sqlite_logs")]
82//!    # struct Logs(sqlx::SqlitePool);
83//!    #
84//!    # #[derive(Responder)]
85//!    # struct Log(String);
86//!    #
87//!    use rocket_db_pools::sqlx::Row;
88//!
89//!    #[get("/<id>")]
90//!    async fn read(db: &Logs, id: i64) -> Option<Log> {
91//!        sqlx::query("SELECT content FROM logs WHERE id = ?").bind(id)
92//!            .fetch_one(&db.0).await
93//!            .and_then(|r| Ok(Log(r.try_get(0)?)))
94//!            .ok()
95//!    }
96//!    # }
97//!    ```
98//!
99//! # Supported Drivers
100//!
101//! At present, this crate supports _four_ drivers: [`deadpool`], [`sqlx`],
102//! [`mongodb`], and [`diesel`]. Each driver may support multiple databases.
103//! Drivers have a varying degree of support for graceful shutdown, affected by
104//! the `Type::init()` fairing on Rocket shutdown.
105//!
106//! ## `deadpool` (v0.12)
107//!
108//! | Database | Feature                     | [`Pool`] Type               | [`Connection`] Deref                 |
109//! |----------|-----------------------------|-----------------------------|--------------------------------------|
110//! | Postgres | `deadpool_postgres` (v0.14) | [`deadpool_postgres::Pool`] | [`deadpool_postgres::ClientWrapper`] |
111//! | Redis    | `deadpool_redis` (v0.16)    | [`deadpool_redis::Pool`]    | [`deadpool_redis::Connection`]       |
112//!
113//! On shutdown, new connections are denied. Shutdown _does not_ wait for
114//! connections to be returned.
115//!
116//! ## `sqlx` (v0.7)
117//!
118//! | Database | Feature         | [`Pool`] Type        | [`Connection`] Deref                     |
119//! |----------|-----------------|----------------------|------------------------------------------|
120//! | Postgres | `sqlx_postgres` | [`sqlx::PgPool`]     | [`sqlx::pool::PoolConnection<Postgres>`] |
121//! | MySQL    | `sqlx_mysql`    | [`sqlx::MySqlPool`]  | [`sqlx::pool::PoolConnection<MySql>`]    |
122//! | SQLite   | `sqlx_sqlite`   | [`sqlx::SqlitePool`] | [`sqlx::pool::PoolConnection<Sqlite>`]   |
123//!
124//! [`sqlx::PgPool`]: https://docs.rs/sqlx/0.6/sqlx/type.PgPool.html
125//! [`sqlx::MySqlPool`]: https://docs.rs/sqlx/0.6/sqlx/type.MySqlPool.html
126//! [`sqlx::SqlitePool`]: https://docs.rs/sqlx/0.6/sqlx/type.SqlitePool.html
127//! [`sqlx::pool::PoolConnection<Postgres>`]: https://docs.rs/sqlx/0.6/sqlx/pool/struct.PoolConnection.html
128//! [`sqlx::pool::PoolConnection<MySql>`]: https://docs.rs/sqlx/0.6/sqlx/pool/struct.PoolConnection.html
129//! [`sqlx::pool::PoolConnection<Sqlite>`]: https://docs.rs/sqlx/0.6/sqlx/pool/struct.PoolConnection.html
130//!
131//! On shutdown, new connections are denied. Shutdown waits for connections to
132//! be returned.
133//!
134//! ## `mongodb` (v3)
135//!
136//! | Database | Feature   | [`Pool`] Type and [`Connection`] Deref |
137//! |----------|-----------|----------------------------------------|
138//! | MongoDB  | `mongodb` | [`mongodb::Client`]                    |
139//!
140//! Graceful shutdown is not supported.
141//!
142//! ## `diesel` (v2)
143//!
144//! | Database | Feature           | [`Pool`] Type         | [`Connection`] Deref             |
145//! |----------|-------------------|-----------------------|----------------------------------|
146//! | Postgres | `diesel_postgres` | [`diesel::PgPool`]    | [`diesel::AsyncPgConnection`]    |
147//! | MySQL    | `diesel_mysql`    | [`diesel::MysqlPool`] | [`diesel::AsyncMysqlConnection`] | //!
148//!
149//! See [`diesel`] for usage details.
150//!
151//! On shutdown, new connections are denied. Shutdown _does not_ wait for
152//! connections to be returned.
153//!
154//! ## Enabling Additional Driver Features
155//!
156//! Only the minimal features for each driver crate are enabled by
157//! `rocket_db_pools`. To use additional driver functionality exposed via its
158//! crate's features, you'll need to depend on the crate directly with those
159//! features enabled in `Cargo.toml`:
160//!
161//! ```toml
162//! [dependencies.sqlx]
163//! version = "0.7"
164//! default-features = false
165//! features = ["macros", "migrate"]
166//!
167//! [dependencies.rocket_db_pools]
168//! version = "0.1.0"
169//! features = ["sqlx_sqlite"]
170//! ```
171//!
172//! # Configuration
173//!
174//! Configuration for a database named `db_name` is deserialized from a
175//! `databases.db_name` configuration parameter into a [`Config`] structure via
176//! Rocket's [configuration facilities](rocket::config). By default,
177//! configuration can be provided in `Rocket.toml`:
178//!
179//! ```toml
180//! [default.databases.db_name]
181//! url = "db.sqlite"
182//!
183//! # Only `url` is required. These have sane defaults and are optional.
184//! min_connections = 64
185//! max_connections = 1024
186//! connect_timeout = 5
187//! idle_timeout = 120
188//!
189//! # This option is only supported by the `sqlx_sqlite` driver.
190//! extensions = ["memvfs", "rot13"]
191//! ```
192//!
193//! Or via environment variables:
194//!
195//! ```sh
196//! ROCKET_DATABASES='{db_name={url="db.sqlite",idle_timeout=120}}'
197//! ```
198//!
199//! See [`Config`] for details on configuration parameters.
200//!
201//! **Note:** `deadpool` and `diesel` drivers do not support and thus ignore the
202//! `min_connections` value.
203//!
204//! ## Driver Defaults
205//!
206//! Some drivers provide configuration defaults different from the underlying
207//! database's defaults. A best-effort attempt is made to document those
208//! differences below:
209//!
210//! * `sqlx_sqlite`
211//!
212//!   - foreign keys   : `enabled`
213//!   - journal mode   : `WAL`
214//!   - create-missing :  `enabled`
215//!   - synchronous    : `full` (even when `WAL`)
216//!   - busy timeout   : `connection_timeout`
217//!
218//! * `sqlx_postgres`
219//!
220//!   - sslmode                  : `prefer`
221//!   - statement-cache-capacity : `100`
222//!   - user                     : result of `whoami`
223//!
224//! * `sqlx_mysql`
225//!
226//!   - sslmode                  : `PREFERRED`
227//!   - statement-cache-capacity : `100`
228//!
229//! # Extending
230//!
231//! Any database driver can implement support for this library by implementing
232//! the [`Pool`] trait.
233
234#![doc(html_root_url = "https://api.rocket.rs/master/rocket_db_pools")]
235#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
236#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
237
238#![deny(missing_docs)]
239
240pub use rocket;
241
242/// Re-export of the `figment` crate.
243#[doc(inline)]
244pub use rocket::figment;
245
246#[cfg(any(feature = "diesel_postgres", feature = "diesel_mysql"))] pub mod diesel;
247#[cfg(feature = "deadpool_postgres")] pub use deadpool_postgres;
248#[cfg(feature = "deadpool_redis")] pub use deadpool_redis;
249#[cfg(feature = "mongodb")] pub use mongodb;
250#[cfg(feature = "sqlx")] pub use sqlx;
251
252mod database;
253mod error;
254mod pool;
255mod config;
256
257pub use self::database::{Connection, Database, Initializer};
258pub use self::error::Error;
259pub use self::pool::Pool;
260pub use self::config::Config;
261
262pub use rocket_db_pools_codegen::*;