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