sqlx_core_oldapi/any/connection/
mod.rs

1use futures_core::future::BoxFuture;
2
3use crate::any::{Any, AnyConnectOptions, AnyKind};
4use crate::connection::Connection;
5use crate::error::Error;
6
7#[cfg(feature = "postgres")]
8use crate::postgres;
9
10#[cfg(feature = "sqlite")]
11use crate::sqlite;
12
13#[cfg(feature = "mssql")]
14use crate::mssql;
15
16#[cfg(feature = "mysql")]
17use crate::mysql;
18
19#[cfg(feature = "odbc")]
20use crate::odbc;
21use crate::transaction::Transaction;
22
23mod establish;
24mod executor;
25
26/// A connection to _any_ SQLx database.
27///
28/// The database driver used is determined by the scheme
29/// of the connection url.
30///
31/// ```text
32/// postgres://postgres@localhost/test
33/// sqlite://a.sqlite
34/// ```
35#[derive(Debug)]
36pub struct AnyConnection(pub(super) AnyConnectionKind);
37
38#[derive(Debug)]
39// Used internally in `sqlx-macros`
40#[doc(hidden)]
41#[allow(clippy::large_enum_variant)]
42pub enum AnyConnectionKind {
43    #[cfg(feature = "postgres")]
44    Postgres(postgres::PgConnection),
45
46    #[cfg(feature = "mssql")]
47    Mssql(mssql::MssqlConnection),
48
49    #[cfg(feature = "mysql")]
50    MySql(mysql::MySqlConnection),
51
52    #[cfg(feature = "sqlite")]
53    Sqlite(sqlite::SqliteConnection),
54
55    #[cfg(feature = "odbc")]
56    Odbc(odbc::OdbcConnection),
57}
58
59impl AnyConnectionKind {
60    pub fn kind(&self) -> AnyKind {
61        match self {
62            #[cfg(feature = "postgres")]
63            AnyConnectionKind::Postgres(_) => AnyKind::Postgres,
64
65            #[cfg(feature = "mysql")]
66            AnyConnectionKind::MySql(_) => AnyKind::MySql,
67
68            #[cfg(feature = "sqlite")]
69            AnyConnectionKind::Sqlite(_) => AnyKind::Sqlite,
70
71            #[cfg(feature = "mssql")]
72            AnyConnectionKind::Mssql(_) => AnyKind::Mssql,
73
74            #[cfg(feature = "odbc")]
75            AnyConnectionKind::Odbc(_) => AnyKind::Odbc,
76        }
77    }
78}
79
80impl AnyConnection {
81    pub fn kind(&self) -> AnyKind {
82        self.0.kind()
83    }
84
85    // Used internally in `sqlx-macros`
86    #[doc(hidden)]
87    pub fn private_get_mut(&mut self) -> &mut AnyConnectionKind {
88        &mut self.0
89    }
90
91    /// Returns the runtime DBMS name for this connection.
92    ///
93    /// For most built-in drivers this returns a well-known constant string:
94    /// - Postgres -> "PostgreSQL"
95    /// - MySQL -> "MySQL"
96    /// - SQLite -> "SQLite"
97    /// - MSSQL -> "Microsoft SQL Server"
98    ///
99    /// For ODBC, this queries the driver at runtime via `SQL_DBMS_NAME`.
100    pub async fn dbms_name(&mut self) -> Result<String, Error> {
101        match &mut self.0 {
102            #[cfg(feature = "postgres")]
103            AnyConnectionKind::Postgres(_) => Ok("PostgreSQL".to_string()),
104
105            #[cfg(feature = "mysql")]
106            AnyConnectionKind::MySql(_) => Ok("MySQL".to_string()),
107
108            #[cfg(feature = "sqlite")]
109            AnyConnectionKind::Sqlite(_) => Ok("SQLite".to_string()),
110
111            #[cfg(feature = "mssql")]
112            AnyConnectionKind::Mssql(_) => Ok("Microsoft SQL Server".to_string()),
113
114            #[cfg(feature = "odbc")]
115            AnyConnectionKind::Odbc(conn) => conn.dbms_name().await,
116        }
117    }
118}
119
120macro_rules! delegate_to {
121    ($self:ident.$method:ident($($arg:ident),*)) => {
122        match &$self.0 {
123            #[cfg(feature = "postgres")]
124            AnyConnectionKind::Postgres(conn) => conn.$method($($arg),*),
125
126            #[cfg(feature = "mysql")]
127            AnyConnectionKind::MySql(conn) => conn.$method($($arg),*),
128
129            #[cfg(feature = "sqlite")]
130            AnyConnectionKind::Sqlite(conn) => conn.$method($($arg),*),
131
132            #[cfg(feature = "mssql")]
133            AnyConnectionKind::Mssql(conn) => conn.$method($($arg),*),
134
135            #[cfg(feature = "odbc")]
136            AnyConnectionKind::Odbc(conn) => conn.$method($($arg),*),
137        }
138    };
139}
140
141macro_rules! delegate_to_mut {
142    ($self:ident.$method:ident($($arg:ident),*)) => {
143        match &mut $self.0 {
144            #[cfg(feature = "postgres")]
145            AnyConnectionKind::Postgres(conn) => conn.$method($($arg),*),
146
147            #[cfg(feature = "mysql")]
148            AnyConnectionKind::MySql(conn) => conn.$method($($arg),*),
149
150            #[cfg(feature = "sqlite")]
151            AnyConnectionKind::Sqlite(conn) => conn.$method($($arg),*),
152
153            #[cfg(feature = "mssql")]
154            AnyConnectionKind::Mssql(conn) => conn.$method($($arg),*),
155
156            #[cfg(feature = "odbc")]
157            AnyConnectionKind::Odbc(conn) => conn.$method($($arg),*),
158        }
159    };
160}
161
162impl Connection for AnyConnection {
163    type Database = Any;
164
165    type Options = AnyConnectOptions;
166
167    fn close(self) -> BoxFuture<'static, Result<(), Error>> {
168        match self.0 {
169            #[cfg(feature = "postgres")]
170            AnyConnectionKind::Postgres(conn) => conn.close(),
171
172            #[cfg(feature = "mysql")]
173            AnyConnectionKind::MySql(conn) => conn.close(),
174
175            #[cfg(feature = "sqlite")]
176            AnyConnectionKind::Sqlite(conn) => conn.close(),
177
178            #[cfg(feature = "mssql")]
179            AnyConnectionKind::Mssql(conn) => conn.close(),
180
181            #[cfg(feature = "odbc")]
182            AnyConnectionKind::Odbc(conn) => conn.close(),
183        }
184    }
185
186    fn close_hard(self) -> BoxFuture<'static, Result<(), Error>> {
187        match self.0 {
188            #[cfg(feature = "postgres")]
189            AnyConnectionKind::Postgres(conn) => conn.close_hard(),
190
191            #[cfg(feature = "mysql")]
192            AnyConnectionKind::MySql(conn) => conn.close_hard(),
193
194            #[cfg(feature = "sqlite")]
195            AnyConnectionKind::Sqlite(conn) => conn.close_hard(),
196
197            #[cfg(feature = "mssql")]
198            AnyConnectionKind::Mssql(conn) => conn.close_hard(),
199
200            #[cfg(feature = "odbc")]
201            AnyConnectionKind::Odbc(conn) => conn.close_hard(),
202        }
203    }
204
205    fn ping(&mut self) -> BoxFuture<'_, Result<(), Error>> {
206        delegate_to_mut!(self.ping())
207    }
208
209    fn begin(&mut self) -> BoxFuture<'_, Result<Transaction<'_, Self::Database>, Error>>
210    where
211        Self: Sized,
212    {
213        Transaction::begin(self)
214    }
215
216    fn cached_statements_size(&self) -> usize {
217        match &self.0 {
218            #[cfg(feature = "postgres")]
219            AnyConnectionKind::Postgres(conn) => conn.cached_statements_size(),
220
221            #[cfg(feature = "mysql")]
222            AnyConnectionKind::MySql(conn) => conn.cached_statements_size(),
223
224            #[cfg(feature = "sqlite")]
225            AnyConnectionKind::Sqlite(conn) => conn.cached_statements_size(),
226
227            // no cache
228            #[cfg(feature = "mssql")]
229            AnyConnectionKind::Mssql(_) => 0,
230
231            // no cache
232            #[cfg(feature = "odbc")]
233            AnyConnectionKind::Odbc(_) => 0,
234        }
235    }
236
237    fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
238        match &mut self.0 {
239            #[cfg(feature = "postgres")]
240            AnyConnectionKind::Postgres(conn) => conn.clear_cached_statements(),
241
242            #[cfg(feature = "mysql")]
243            AnyConnectionKind::MySql(conn) => conn.clear_cached_statements(),
244
245            #[cfg(feature = "sqlite")]
246            AnyConnectionKind::Sqlite(conn) => conn.clear_cached_statements(),
247
248            // no cache
249            #[cfg(feature = "mssql")]
250            AnyConnectionKind::Mssql(_) => Box::pin(futures_util::future::ok(())),
251
252            // no cache
253            #[cfg(feature = "odbc")]
254            AnyConnectionKind::Odbc(_) => Box::pin(futures_util::future::ok(())),
255        }
256    }
257
258    #[doc(hidden)]
259    fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
260        delegate_to_mut!(self.flush())
261    }
262
263    #[doc(hidden)]
264    fn should_flush(&self) -> bool {
265        delegate_to!(self.should_flush())
266    }
267}
268
269#[cfg(feature = "postgres")]
270impl From<postgres::PgConnection> for AnyConnection {
271    fn from(conn: postgres::PgConnection) -> Self {
272        AnyConnection(AnyConnectionKind::Postgres(conn))
273    }
274}
275
276#[cfg(feature = "mssql")]
277impl From<mssql::MssqlConnection> for AnyConnection {
278    fn from(conn: mssql::MssqlConnection) -> Self {
279        AnyConnection(AnyConnectionKind::Mssql(conn))
280    }
281}
282
283#[cfg(feature = "mysql")]
284impl From<mysql::MySqlConnection> for AnyConnection {
285    fn from(conn: mysql::MySqlConnection) -> Self {
286        AnyConnection(AnyConnectionKind::MySql(conn))
287    }
288}
289
290#[cfg(feature = "sqlite")]
291impl From<sqlite::SqliteConnection> for AnyConnection {
292    fn from(conn: sqlite::SqliteConnection) -> Self {
293        AnyConnection(AnyConnectionKind::Sqlite(conn))
294    }
295}
296
297#[cfg(feature = "odbc")]
298impl From<odbc::OdbcConnection> for AnyConnection {
299    fn from(conn: odbc::OdbcConnection) -> Self {
300        AnyConnection(AnyConnectionKind::Odbc(conn))
301    }
302}