1use std::{marker::PhantomData, str::FromStr as _};
2
3pub use mobc;
4use mobc::{Manager, async_trait};
5pub use sqlx;
6use sqlx::{Connection, Database};
7
8mod migrator;
9pub use migrator::SqlxMigrationExt;
10
11pub struct SqlxConnectionManager<DB>
12where
13 DB: Database + Sync,
14{
15 connect_options: <DB::Connection as Connection>::Options,
16 _phantom: PhantomData<DB>,
17}
18
19impl<DB> SqlxConnectionManager<DB>
20where
21 DB: Database + Sync,
22{
23 #[must_use]
24 pub fn new(
25 connect_options: <DB::Connection as Connection>::Options,
26 ) -> Self {
27 Self {
28 connect_options,
29 _phantom: PhantomData,
30 }
31 }
32
33 pub fn from_url(url: &str) -> Result<Self, sqlx::Error> {
34 let options = <DB::Connection as Connection>::Options::from_str(url)?;
35 Ok(Self::new(options))
36 }
37}
38
39#[async_trait]
40impl<DB> Manager for SqlxConnectionManager<DB>
41where
42 DB: Database + Sync,
43{
44 type Connection = DB::Connection;
45 type Error = sqlx::Error;
46
47 async fn connect(&self) -> Result<Self::Connection, Self::Error> {
48 Self::Connection::connect_with(&self.connect_options).await
49 }
50
51 async fn check(
52 &self,
53 mut conn: Self::Connection,
54 ) -> Result<Self::Connection, Self::Error> {
55 conn.ping().await.map(|()| conn)
56 }
57}