sqlx_core_oldapi/any/
options.rs

1use crate::any::AnyConnection;
2use crate::connection::ConnectOptions;
3use crate::error::Error;
4use futures_core::future::BoxFuture;
5use log::LevelFilter;
6use std::str::FromStr;
7use std::time::Duration;
8
9#[cfg(feature = "postgres")]
10use crate::postgres::PgConnectOptions;
11
12#[cfg(feature = "mysql")]
13use crate::mysql::MySqlConnectOptions;
14
15#[cfg(feature = "sqlite")]
16use crate::sqlite::SqliteConnectOptions;
17
18use crate::any::kind::AnyKind;
19#[cfg(feature = "mssql")]
20use crate::mssql::MssqlConnectOptions;
21
22/// Opaque options for connecting to a database. These may only be constructed by parsing from
23/// a connection url.
24///
25/// ```text
26/// postgres://postgres:password@localhost/database
27/// mysql://root:password@localhost/database
28/// ```
29#[derive(Debug, Clone)]
30pub struct AnyConnectOptions(pub(crate) AnyConnectOptionsKind);
31
32impl AnyConnectOptions {
33    pub fn kind(&self) -> AnyKind {
34        match &self.0 {
35            #[cfg(feature = "postgres")]
36            AnyConnectOptionsKind::Postgres(_) => AnyKind::Postgres,
37
38            #[cfg(feature = "mysql")]
39            AnyConnectOptionsKind::MySql(_) => AnyKind::MySql,
40
41            #[cfg(feature = "sqlite")]
42            AnyConnectOptionsKind::Sqlite(_) => AnyKind::Sqlite,
43
44            #[cfg(feature = "mssql")]
45            AnyConnectOptionsKind::Mssql(_) => AnyKind::Mssql,
46        }
47    }
48}
49
50macro_rules! try_from_any_connect_options_to {
51    ($to:ty, $kind:path, $name:expr) => {
52        impl TryFrom<AnyConnectOptions> for $to {
53            type Error = Error;
54
55            fn try_from(value: AnyConnectOptions) -> Result<Self, Self::Error> {
56                #[allow(irrefutable_let_patterns)]
57                if let $kind(connect_options) = value.0 {
58                    Ok(connect_options)
59                } else {
60                    Err(Error::Configuration(
61                        format!("Not {} typed AnyConnectOptions", $name).into(),
62                    ))
63                }
64            }
65        }
66
67        impl AnyConnectOptions {
68            paste::item! {
69                pub fn [< as_ $name >] (&self) -> Option<&$to> {
70                    #[allow(irrefutable_let_patterns)]
71                    if let $kind(ref connect_options) = self.0 {
72                        Some(connect_options)
73                    } else {
74                        None
75                    }
76                }
77
78                pub fn [< as_ $name _mut >] (&mut self) -> Option<&mut $to> {
79                    #[allow(irrefutable_let_patterns)]
80                    if let $kind(ref mut connect_options) = self.0 {
81                        Some(connect_options)
82                    } else {
83                        None
84                    }
85                }
86            }
87        }
88    };
89}
90
91#[cfg(feature = "postgres")]
92try_from_any_connect_options_to!(
93    PgConnectOptions,
94    AnyConnectOptionsKind::Postgres,
95    "postgres"
96);
97
98#[cfg(feature = "mysql")]
99try_from_any_connect_options_to!(MySqlConnectOptions, AnyConnectOptionsKind::MySql, "mysql");
100
101#[cfg(feature = "sqlite")]
102try_from_any_connect_options_to!(
103    SqliteConnectOptions,
104    AnyConnectOptionsKind::Sqlite,
105    "sqlite"
106);
107
108#[cfg(feature = "mssql")]
109try_from_any_connect_options_to!(MssqlConnectOptions, AnyConnectOptionsKind::Mssql, "mssql");
110
111#[derive(Debug, Clone)]
112pub(crate) enum AnyConnectOptionsKind {
113    #[cfg(feature = "postgres")]
114    Postgres(PgConnectOptions),
115
116    #[cfg(feature = "mysql")]
117    MySql(MySqlConnectOptions),
118
119    #[cfg(feature = "sqlite")]
120    Sqlite(SqliteConnectOptions),
121
122    #[cfg(feature = "mssql")]
123    Mssql(MssqlConnectOptions),
124}
125
126#[cfg(feature = "postgres")]
127impl From<PgConnectOptions> for AnyConnectOptions {
128    fn from(options: PgConnectOptions) -> Self {
129        Self(AnyConnectOptionsKind::Postgres(options))
130    }
131}
132
133#[cfg(feature = "mysql")]
134impl From<MySqlConnectOptions> for AnyConnectOptions {
135    fn from(options: MySqlConnectOptions) -> Self {
136        Self(AnyConnectOptionsKind::MySql(options))
137    }
138}
139
140#[cfg(feature = "sqlite")]
141impl From<SqliteConnectOptions> for AnyConnectOptions {
142    fn from(options: SqliteConnectOptions) -> Self {
143        Self(AnyConnectOptionsKind::Sqlite(options))
144    }
145}
146
147#[cfg(feature = "mssql")]
148impl From<MssqlConnectOptions> for AnyConnectOptions {
149    fn from(options: MssqlConnectOptions) -> Self {
150        Self(AnyConnectOptionsKind::Mssql(options))
151    }
152}
153
154impl FromStr for AnyConnectOptions {
155    type Err = Error;
156
157    fn from_str(url: &str) -> Result<Self, Self::Err> {
158        match AnyKind::from_str(url)? {
159            #[cfg(feature = "postgres")]
160            AnyKind::Postgres => {
161                PgConnectOptions::from_str(url).map(AnyConnectOptionsKind::Postgres)
162            }
163
164            #[cfg(feature = "mysql")]
165            AnyKind::MySql => MySqlConnectOptions::from_str(url).map(AnyConnectOptionsKind::MySql),
166
167            #[cfg(feature = "sqlite")]
168            AnyKind::Sqlite => {
169                SqliteConnectOptions::from_str(url).map(AnyConnectOptionsKind::Sqlite)
170            }
171
172            #[cfg(feature = "mssql")]
173            AnyKind::Mssql => MssqlConnectOptions::from_str(url).map(AnyConnectOptionsKind::Mssql),
174        }
175        .map(AnyConnectOptions)
176    }
177}
178
179impl ConnectOptions for AnyConnectOptions {
180    type Connection = AnyConnection;
181
182    #[inline]
183    fn connect(&self) -> BoxFuture<'_, Result<AnyConnection, Error>> {
184        Box::pin(AnyConnection::establish(self))
185    }
186
187    fn log_statements(&mut self, level: LevelFilter) -> &mut Self {
188        match &mut self.0 {
189            #[cfg(feature = "postgres")]
190            AnyConnectOptionsKind::Postgres(o) => {
191                o.log_statements(level);
192            }
193
194            #[cfg(feature = "mysql")]
195            AnyConnectOptionsKind::MySql(o) => {
196                o.log_statements(level);
197            }
198
199            #[cfg(feature = "sqlite")]
200            AnyConnectOptionsKind::Sqlite(o) => {
201                o.log_statements(level);
202            }
203
204            #[cfg(feature = "mssql")]
205            AnyConnectOptionsKind::Mssql(o) => {
206                o.log_statements(level);
207            }
208        };
209        self
210    }
211
212    fn log_slow_statements(&mut self, level: LevelFilter, duration: Duration) -> &mut Self {
213        match &mut self.0 {
214            #[cfg(feature = "postgres")]
215            AnyConnectOptionsKind::Postgres(o) => {
216                o.log_slow_statements(level, duration);
217            }
218
219            #[cfg(feature = "mysql")]
220            AnyConnectOptionsKind::MySql(o) => {
221                o.log_slow_statements(level, duration);
222            }
223
224            #[cfg(feature = "sqlite")]
225            AnyConnectOptionsKind::Sqlite(o) => {
226                o.log_slow_statements(level, duration);
227            }
228
229            #[cfg(feature = "mssql")]
230            AnyConnectOptionsKind::Mssql(o) => {
231                o.log_slow_statements(level, duration);
232            }
233        };
234        self
235    }
236}