diff --git a/sqlx-core/src/any/connection/mod.rs b/sqlx-core/src/any/connection/mod.rs index a0d71378b5..c8c8b45809 100644 --- a/sqlx-core/src/any/connection/mod.rs +++ b/sqlx-core/src/any/connection/mod.rs @@ -87,34 +87,6 @@ impl AnyConnection { pub fn private_get_mut(&mut self) -> &mut AnyConnectionKind { &mut self.0 } - - /// Returns the runtime DBMS name for this connection. - /// - /// For most built-in drivers this returns a well-known constant string: - /// - Postgres -> "PostgreSQL" - /// - MySQL -> "MySQL" - /// - SQLite -> "SQLite" - /// - MSSQL -> "Microsoft SQL Server" - /// - /// For ODBC, this queries the driver at runtime via `SQL_DBMS_NAME`. - pub async fn dbms_name(&mut self) -> Result { - match &mut self.0 { - #[cfg(feature = "postgres")] - AnyConnectionKind::Postgres(_) => Ok("PostgreSQL".to_string()), - - #[cfg(feature = "mysql")] - AnyConnectionKind::MySql(_) => Ok("MySQL".to_string()), - - #[cfg(feature = "sqlite")] - AnyConnectionKind::Sqlite(_) => Ok("SQLite".to_string()), - - #[cfg(feature = "mssql")] - AnyConnectionKind::Mssql(_) => Ok("Microsoft SQL Server".to_string()), - - #[cfg(feature = "odbc")] - AnyConnectionKind::Odbc(conn) => conn.dbms_name().await, - } - } } macro_rules! delegate_to { @@ -264,6 +236,25 @@ impl Connection for AnyConnection { fn should_flush(&self) -> bool { delegate_to!(self.should_flush()) } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + match &mut self.0 { + #[cfg(feature = "postgres")] + AnyConnectionKind::Postgres(conn) => conn.dbms_name(), + + #[cfg(feature = "mysql")] + AnyConnectionKind::MySql(conn) => conn.dbms_name(), + + #[cfg(feature = "sqlite")] + AnyConnectionKind::Sqlite(conn) => conn.dbms_name(), + + #[cfg(feature = "mssql")] + AnyConnectionKind::Mssql(conn) => conn.dbms_name(), + + #[cfg(feature = "odbc")] + AnyConnectionKind::Odbc(conn) => conn.dbms_name(), + } + } } #[cfg(feature = "postgres")] diff --git a/sqlx-core/src/connection.rs b/sqlx-core/src/connection.rs index ae0ae0d649..11c5f21708 100644 --- a/sqlx-core/src/connection.rs +++ b/sqlx-core/src/connection.rs @@ -102,6 +102,25 @@ pub trait Connection: Send { Box::pin(async move { Ok(()) }) } + /// Returns the name of the Database Management System (DBMS) this connection + /// is talking to. + /// + /// This is intended to be compatible with the ODBC `SQL_DBMS_NAME` info value + /// and should generally return the same string as an ODBC driver for the same + /// database. This makes it easier to write conditional SQL or feature probes + /// that work across both native and ODBC connections. + /// + /// Typical return values include: + /// - "PostgreSQL" + /// - "MySQL" + /// - "SQLite" + /// - "Microsoft SQL Server" (includes Azure SQL) + /// - ODBC: the exact string reported by the driver via `SQL_DBMS_NAME` + /// + /// Implementations for built-in drivers return a well-known constant string, + /// while the ODBC driver queries the underlying driver at runtime. + fn dbms_name(&mut self) -> BoxFuture<'_, Result>; + #[doc(hidden)] fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>>; diff --git a/sqlx-core/src/mssql/connection/mod.rs b/sqlx-core/src/mssql/connection/mod.rs index 5ba9e95dd0..a3aac85f88 100644 --- a/sqlx-core/src/mssql/connection/mod.rs +++ b/sqlx-core/src/mssql/connection/mod.rs @@ -81,4 +81,8 @@ impl Connection for MssqlConnection { fn should_flush(&self) -> bool { !self.stream.wbuf.is_empty() } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + futures_util::future::ready(Ok("Microsoft SQL Server".to_string())).boxed() + } } diff --git a/sqlx-core/src/mysql/connection/mod.rs b/sqlx-core/src/mysql/connection/mod.rs index 1f87eaa918..8401798f61 100644 --- a/sqlx-core/src/mysql/connection/mod.rs +++ b/sqlx-core/src/mysql/connection/mod.rs @@ -107,4 +107,8 @@ impl Connection for MySqlConnection { { Transaction::begin(self) } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + futures_util::future::ready(Ok("MySQL".to_string())).boxed() + } } diff --git a/sqlx-core/src/odbc/connection/mod.rs b/sqlx-core/src/odbc/connection/mod.rs index 84d5572c84..391f118351 100644 --- a/sqlx-core/src/odbc/connection/mod.rs +++ b/sqlx-core/src/odbc/connection/mod.rs @@ -95,14 +95,7 @@ impl OdbcConnection { }) } - /// Returns the name of the actual Database Management System (DBMS) this - /// connection is talking to as reported by the ODBC driver. - pub async fn dbms_name(&mut self) -> Result { - self.with_conn("dbms_name", move |conn| { - Ok(conn.database_management_system_name()?) - }) - .await - } + // (dbms_name moved to the Connection trait implementation) pub(crate) async fn ping_blocking(&mut self) -> Result<(), Error> { self.with_conn("ping", move |conn| { @@ -237,6 +230,15 @@ impl Connection for OdbcConnection { fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> { Box::pin(self.clear_cached_statements()) } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + Box::pin(async move { + self.with_conn("dbms_name", move |conn| { + Ok(conn.database_management_system_name()?) + }) + .await + }) + } } // moved helpers to connection/inner.rs diff --git a/sqlx-core/src/postgres/connection/mod.rs b/sqlx-core/src/postgres/connection/mod.rs index 325b565c3b..5c6e7bd429 100644 --- a/sqlx-core/src/postgres/connection/mod.rs +++ b/sqlx-core/src/postgres/connection/mod.rs @@ -205,4 +205,8 @@ impl Connection for PgConnection { fn should_flush(&self) -> bool { !self.stream.wbuf.is_empty() } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + futures_util::future::ready(Ok("PostgreSQL".to_string())).boxed() + } } diff --git a/sqlx-core/src/sqlite/connection/mod.rs b/sqlx-core/src/sqlite/connection/mod.rs index 9a43e3f9c2..0ed5c0f1db 100644 --- a/sqlx-core/src/sqlite/connection/mod.rs +++ b/sqlx-core/src/sqlite/connection/mod.rs @@ -202,6 +202,10 @@ impl Connection for SqliteConnection { fn should_flush(&self) -> bool { false } + + fn dbms_name(&mut self) -> BoxFuture<'_, Result> { + Box::pin(async move { Ok("SQLite".to_string()) }) + } } impl LockedSqliteHandle<'_> {