xdl_database/
connection.rs

1//! Database connection management
2
3use crate::drivers;
4use crate::{DatabaseError, DatabaseResult, DatabaseType, Recordset};
5
6/// Database connection enum that wraps different database drivers
7#[derive(Debug)]
8pub enum DatabaseConnection {
9    #[cfg(feature = "postgres-support")]
10    PostgreSQL(drivers::postgres::PostgresConnection),
11
12    #[cfg(feature = "mysql-support")]
13    MySQL(drivers::mysql::MySQLConnection),
14
15    #[cfg(feature = "duckdb-support")]
16    DuckDB(drivers::duckdb::DuckDBConnection),
17
18    #[cfg(feature = "sqlite-support")]
19    SQLite(drivers::sqlite::SQLiteConnection),
20
21    #[cfg(feature = "odbc-support")]
22    ODBC(drivers::odbc::ODBCConnection),
23
24    #[cfg(feature = "redis-support")]
25    Redis(drivers::redis_driver::RedisConnection),
26
27    #[cfg(feature = "kafka-support")]
28    Kafka(drivers::kafka::KafkaConnection),
29
30    Unsupported(String),
31}
32
33impl DatabaseConnection {
34    /// Create a new connection based on connection string and database type
35    pub async fn new(connection_string: &str, db_type: DatabaseType) -> DatabaseResult<Self> {
36        match db_type {
37            #[cfg(feature = "postgres-support")]
38            DatabaseType::PostgreSQL => {
39                let conn =
40                    drivers::postgres::PostgresConnection::connect(connection_string).await?;
41                Ok(DatabaseConnection::PostgreSQL(conn))
42            }
43
44            #[cfg(feature = "mysql-support")]
45            DatabaseType::MySQL => {
46                let conn = drivers::mysql::MySQLConnection::connect(connection_string).await?;
47                Ok(DatabaseConnection::MySQL(conn))
48            }
49
50            #[cfg(feature = "duckdb-support")]
51            DatabaseType::DuckDB => {
52                let conn = drivers::duckdb::DuckDBConnection::connect(connection_string).await?;
53                Ok(DatabaseConnection::DuckDB(conn))
54            }
55
56            #[cfg(feature = "sqlite-support")]
57            DatabaseType::SQLite => {
58                let conn = drivers::sqlite::SQLiteConnection::connect(connection_string).await?;
59                Ok(DatabaseConnection::SQLite(conn))
60            }
61
62            #[cfg(feature = "odbc-support")]
63            DatabaseType::ODBC => {
64                let conn = drivers::odbc::ODBCConnection::connect(connection_string).await?;
65                Ok(DatabaseConnection::ODBC(conn))
66            }
67
68            #[cfg(feature = "redis-support")]
69            DatabaseType::Redis => {
70                let conn =
71                    drivers::redis_driver::RedisConnection::connect(connection_string).await?;
72                Ok(DatabaseConnection::Redis(conn))
73            }
74
75            #[cfg(feature = "kafka-support")]
76            DatabaseType::Kafka => {
77                let conn = drivers::kafka::KafkaConnection::connect(connection_string).await?;
78                Ok(DatabaseConnection::Kafka(conn))
79            }
80
81            _ => Ok(DatabaseConnection::Unsupported(format!("{:?}", db_type))),
82        }
83    }
84
85    /// Execute a query and return results
86    pub async fn execute(&self, query: &str) -> DatabaseResult<Recordset> {
87        match self {
88            #[cfg(feature = "postgres-support")]
89            DatabaseConnection::PostgreSQL(conn) => conn.execute(query).await,
90
91            #[cfg(feature = "mysql-support")]
92            DatabaseConnection::MySQL(conn) => conn.execute(query).await,
93
94            #[cfg(feature = "duckdb-support")]
95            DatabaseConnection::DuckDB(conn) => conn.execute(query).await,
96
97            #[cfg(feature = "sqlite-support")]
98            DatabaseConnection::SQLite(conn) => conn.execute(query).await,
99
100            #[cfg(feature = "odbc-support")]
101            DatabaseConnection::ODBC(conn) => conn.execute(query).await,
102
103            #[cfg(feature = "redis-support")]
104            DatabaseConnection::Redis(conn) => conn.execute(query).await,
105
106            #[cfg(feature = "kafka-support")]
107            DatabaseConnection::Kafka(conn) => conn.execute(query).await,
108
109            DatabaseConnection::Unsupported(db_type) => {
110                Err(DatabaseError::UnsupportedDatabase(db_type.clone()))
111            }
112        }
113    }
114
115    /// Execute a command (INSERT, UPDATE, DELETE) and return rows affected
116    pub async fn execute_command(&self, command: &str) -> DatabaseResult<u64> {
117        match self {
118            #[cfg(feature = "postgres-support")]
119            DatabaseConnection::PostgreSQL(conn) => conn.execute_command(command).await,
120
121            #[cfg(feature = "mysql-support")]
122            DatabaseConnection::MySQL(conn) => conn.execute_command(command).await,
123
124            #[cfg(feature = "duckdb-support")]
125            DatabaseConnection::DuckDB(conn) => conn.execute_command(command).await,
126
127            #[cfg(feature = "sqlite-support")]
128            DatabaseConnection::SQLite(conn) => conn.execute_command(command).await,
129
130            #[cfg(feature = "odbc-support")]
131            DatabaseConnection::ODBC(conn) => conn.execute_command(command).await,
132
133            #[cfg(feature = "redis-support")]
134            DatabaseConnection::Redis(conn) => conn.execute_command(command).await,
135
136            #[cfg(feature = "kafka-support")]
137            DatabaseConnection::Kafka(conn) => conn.execute_command(command).await,
138
139            DatabaseConnection::Unsupported(db_type) => {
140                Err(DatabaseError::UnsupportedDatabase(db_type.clone()))
141            }
142        }
143    }
144
145    /// Close the connection
146    pub async fn close(&mut self) -> DatabaseResult<()> {
147        match self {
148            #[cfg(feature = "postgres-support")]
149            DatabaseConnection::PostgreSQL(conn) => conn.close().await,
150
151            #[cfg(feature = "mysql-support")]
152            DatabaseConnection::MySQL(conn) => conn.close().await,
153
154            #[cfg(feature = "duckdb-support")]
155            DatabaseConnection::DuckDB(conn) => conn.close().await,
156
157            #[cfg(feature = "sqlite-support")]
158            DatabaseConnection::SQLite(conn) => conn.close().await,
159
160            #[cfg(feature = "odbc-support")]
161            DatabaseConnection::ODBC(conn) => conn.close().await,
162
163            #[cfg(feature = "redis-support")]
164            DatabaseConnection::Redis(conn) => conn.close().await,
165
166            #[cfg(feature = "kafka-support")]
167            DatabaseConnection::Kafka(conn) => conn.close().await,
168
169            DatabaseConnection::Unsupported(_) => Ok(()),
170        }
171    }
172
173    /// Check if connection is alive
174    pub async fn is_connected(&self) -> bool {
175        match self {
176            #[cfg(feature = "postgres-support")]
177            DatabaseConnection::PostgreSQL(conn) => conn.is_connected().await,
178
179            #[cfg(feature = "mysql-support")]
180            DatabaseConnection::MySQL(conn) => conn.is_connected().await,
181
182            #[cfg(feature = "duckdb-support")]
183            DatabaseConnection::DuckDB(conn) => conn.is_connected().await,
184
185            #[cfg(feature = "sqlite-support")]
186            DatabaseConnection::SQLite(conn) => conn.is_connected().await,
187
188            #[cfg(feature = "odbc-support")]
189            DatabaseConnection::ODBC(conn) => conn.is_connected().await,
190
191            #[cfg(feature = "redis-support")]
192            DatabaseConnection::Redis(conn) => conn.is_connected().await,
193
194            #[cfg(feature = "kafka-support")]
195            DatabaseConnection::Kafka(conn) => conn.is_connected().await,
196
197            DatabaseConnection::Unsupported(_) => false,
198        }
199    }
200}