Skip to main content

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, $as_ref:ident, $as_mut:ident) => {
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            pub fn $as_ref(&self) -> Option<&$to> {
74                #[allow(irrefutable_let_patterns)]
75                if let $kind(ref connect_options) = self.0 {
76                    Some(connect_options)
77                } else {
78                    None
79                }
80            }
81
82            pub fn $as_mut(&mut self) -> Option<&mut $to> {
83                #[allow(irrefutable_let_patterns)]
84                if let $kind(ref mut connect_options) = self.0 {
85                    Some(connect_options)
86                } else {
87                    None
88                }
89            }
90        }
91    };
92}
93
94#[cfg(feature = "postgres")]
95try_from_any_connect_options_to!(
96    PgConnectOptions,
97    AnyConnectOptionsKind::Postgres,
98    "postgres",
99    as_postgres,
100    as_postgres_mut
101);
102
103#[cfg(feature = "mysql")]
104try_from_any_connect_options_to!(
105    MySqlConnectOptions,
106    AnyConnectOptionsKind::MySql,
107    "mysql",
108    as_mysql,
109    as_mysql_mut
110);
111
112#[cfg(feature = "sqlite")]
113try_from_any_connect_options_to!(
114    SqliteConnectOptions,
115    AnyConnectOptionsKind::Sqlite,
116    "sqlite",
117    as_sqlite,
118    as_sqlite_mut
119);
120
121#[cfg(feature = "mssql")]
122try_from_any_connect_options_to!(
123    MssqlConnectOptions,
124    AnyConnectOptionsKind::Mssql,
125    "mssql",
126    as_mssql,
127    as_mssql_mut
128);
129
130#[cfg(feature = "odbc")]
131try_from_any_connect_options_to!(
132    OdbcConnectOptions,
133    AnyConnectOptionsKind::Odbc,
134    "odbc",
135    as_odbc,
136    as_odbc_mut
137);
138
139#[derive(Debug, Clone)]
140pub(crate) enum AnyConnectOptionsKind {
141    #[cfg(feature = "postgres")]
142    Postgres(PgConnectOptions),
143
144    #[cfg(feature = "mysql")]
145    MySql(MySqlConnectOptions),
146
147    #[cfg(feature = "sqlite")]
148    Sqlite(SqliteConnectOptions),
149
150    #[cfg(feature = "mssql")]
151    Mssql(MssqlConnectOptions),
152
153    #[cfg(feature = "odbc")]
154    Odbc(OdbcConnectOptions),
155}
156
157#[cfg(feature = "postgres")]
158impl From<PgConnectOptions> for AnyConnectOptions {
159    fn from(options: PgConnectOptions) -> Self {
160        Self(AnyConnectOptionsKind::Postgres(options))
161    }
162}
163
164#[cfg(feature = "mysql")]
165impl From<MySqlConnectOptions> for AnyConnectOptions {
166    fn from(options: MySqlConnectOptions) -> Self {
167        Self(AnyConnectOptionsKind::MySql(options))
168    }
169}
170
171#[cfg(feature = "sqlite")]
172impl From<SqliteConnectOptions> for AnyConnectOptions {
173    fn from(options: SqliteConnectOptions) -> Self {
174        Self(AnyConnectOptionsKind::Sqlite(options))
175    }
176}
177
178#[cfg(feature = "mssql")]
179impl From<MssqlConnectOptions> for AnyConnectOptions {
180    fn from(options: MssqlConnectOptions) -> Self {
181        Self(AnyConnectOptionsKind::Mssql(options))
182    }
183}
184
185#[cfg(feature = "odbc")]
186impl From<OdbcConnectOptions> for AnyConnectOptions {
187    fn from(options: OdbcConnectOptions) -> Self {
188        Self(AnyConnectOptionsKind::Odbc(options))
189    }
190}
191
192impl FromStr for AnyConnectOptions {
193    type Err = Error;
194
195    fn from_str(url: &str) -> Result<Self, Self::Err> {
196        match AnyKind::from_str(url)? {
197            #[cfg(feature = "postgres")]
198            AnyKind::Postgres => {
199                PgConnectOptions::from_str(url).map(AnyConnectOptionsKind::Postgres)
200            }
201
202            #[cfg(feature = "mysql")]
203            AnyKind::MySql => MySqlConnectOptions::from_str(url).map(AnyConnectOptionsKind::MySql),
204
205            #[cfg(feature = "sqlite")]
206            AnyKind::Sqlite => {
207                SqliteConnectOptions::from_str(url).map(AnyConnectOptionsKind::Sqlite)
208            }
209
210            #[cfg(feature = "mssql")]
211            AnyKind::Mssql => MssqlConnectOptions::from_str(url).map(AnyConnectOptionsKind::Mssql),
212
213            #[cfg(feature = "odbc")]
214            AnyKind::Odbc => OdbcConnectOptions::from_str(url).map(AnyConnectOptionsKind::Odbc),
215        }
216        .map(AnyConnectOptions)
217    }
218}
219
220impl ConnectOptions for AnyConnectOptions {
221    type Connection = AnyConnection;
222
223    #[inline]
224    fn connect(&self) -> BoxFuture<'_, Result<AnyConnection, Error>> {
225        Box::pin(AnyConnection::establish(self))
226    }
227
228    fn log_statements(&mut self, level: LevelFilter) -> &mut Self {
229        match &mut self.0 {
230            #[cfg(feature = "postgres")]
231            AnyConnectOptionsKind::Postgres(o) => {
232                o.log_statements(level);
233            }
234
235            #[cfg(feature = "mysql")]
236            AnyConnectOptionsKind::MySql(o) => {
237                o.log_statements(level);
238            }
239
240            #[cfg(feature = "sqlite")]
241            AnyConnectOptionsKind::Sqlite(o) => {
242                o.log_statements(level);
243            }
244
245            #[cfg(feature = "mssql")]
246            AnyConnectOptionsKind::Mssql(o) => {
247                o.log_statements(level);
248            }
249
250            #[cfg(feature = "odbc")]
251            AnyConnectOptionsKind::Odbc(o) => {
252                o.log_statements(level);
253            }
254        };
255        self
256    }
257
258    fn log_slow_statements(&mut self, level: LevelFilter, duration: Duration) -> &mut Self {
259        match &mut self.0 {
260            #[cfg(feature = "postgres")]
261            AnyConnectOptionsKind::Postgres(o) => {
262                o.log_slow_statements(level, duration);
263            }
264
265            #[cfg(feature = "mysql")]
266            AnyConnectOptionsKind::MySql(o) => {
267                o.log_slow_statements(level, duration);
268            }
269
270            #[cfg(feature = "sqlite")]
271            AnyConnectOptionsKind::Sqlite(o) => {
272                o.log_slow_statements(level, duration);
273            }
274
275            #[cfg(feature = "mssql")]
276            AnyConnectOptionsKind::Mssql(o) => {
277                o.log_slow_statements(level, duration);
278            }
279
280            #[cfg(feature = "odbc")]
281            AnyConnectOptionsKind::Odbc(o) => {
282                o.log_slow_statements(level, duration);
283            }
284        };
285        self
286    }
287}