burncloud_database_client/
client.rs

1use burncloud_database_core::{
2    DatabaseConnection, QueryExecutor, TransactionManager, Transaction,
3    QueryContext, QueryOptions, QueryResult, QueryParam
4};
5use burncloud_database_core::error::{DatabaseResult, DatabaseError};
6use async_trait::async_trait;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9use tracing::{info, error, debug};
10
11pub struct DatabaseClient {
12    connection: Arc<RwLock<Box<dyn DatabaseConnection>>>,
13    query_executor: Arc<Box<dyn QueryExecutor>>,
14}
15
16impl DatabaseClient {
17    pub fn new(
18        connection: Box<dyn DatabaseConnection>,
19        query_executor: Box<dyn QueryExecutor>,
20    ) -> Self {
21        Self {
22            connection: Arc::new(RwLock::new(connection)),
23            query_executor: Arc::new(query_executor),
24        }
25    }
26
27    pub async fn connect(&self) -> DatabaseResult<()> {
28        let mut conn = self.connection.write().await;
29        info!("Connecting to database...");
30        conn.connect().await?;
31        info!("Successfully connected to database");
32        Ok(())
33    }
34
35    pub async fn disconnect(&self) -> DatabaseResult<()> {
36        let mut conn = self.connection.write().await;
37        info!("Disconnecting from database...");
38        conn.disconnect().await?;
39        info!("Successfully disconnected from database");
40        Ok(())
41    }
42
43    pub async fn is_connected(&self) -> bool {
44        let conn = self.connection.read().await;
45        conn.is_connected().await
46    }
47
48    pub async fn ping(&self) -> DatabaseResult<()> {
49        let conn = self.connection.read().await;
50        debug!("Pinging database...");
51        conn.ping().await?;
52        debug!("Database ping successful");
53        Ok(())
54    }
55
56    pub async fn execute_query(
57        &self,
58        query: &str,
59        params: &[&dyn QueryParam],
60        context: &QueryContext,
61    ) -> DatabaseResult<QueryResult> {
62        debug!("Executing query: {}", query);
63        let result = self.query_executor.execute_query(query, params, context).await;
64
65        match &result {
66            Ok(res) => debug!("Query executed successfully, {} rows returned", res.rows.len()),
67            Err(e) => error!("Query execution failed: {}", e),
68        }
69
70        result
71    }
72
73    pub async fn execute_query_with_options(
74        &self,
75        query: &str,
76        params: &[&dyn QueryParam],
77        options: &QueryOptions,
78        context: &QueryContext,
79    ) -> DatabaseResult<QueryResult> {
80        debug!("Executing query with options: {}", query);
81        let result = self.query_executor.execute_query_with_options(query, params, options, context).await;
82
83        match &result {
84            Ok(res) => debug!("Query with options executed successfully, {} rows returned", res.rows.len()),
85            Err(e) => error!("Query with options execution failed: {}", e),
86        }
87
88        result
89    }
90}
91
92#[async_trait]
93impl DatabaseConnection for DatabaseClient {
94    async fn connect(&mut self) -> DatabaseResult<()> {
95        self.connect().await
96    }
97
98    async fn disconnect(&mut self) -> DatabaseResult<()> {
99        self.disconnect().await
100    }
101
102    async fn is_connected(&self) -> bool {
103        self.is_connected().await
104    }
105
106    async fn ping(&self) -> DatabaseResult<()> {
107        self.ping().await
108    }
109}
110
111#[async_trait]
112impl QueryExecutor for DatabaseClient {
113    async fn execute_query(
114        &self,
115        query: &str,
116        params: &[&dyn QueryParam],
117        context: &QueryContext,
118    ) -> DatabaseResult<QueryResult> {
119        self.execute_query(query, params, context).await
120    }
121
122    async fn execute_query_with_options(
123        &self,
124        query: &str,
125        params: &[&dyn QueryParam],
126        options: &QueryOptions,
127        context: &QueryContext,
128    ) -> DatabaseResult<QueryResult> {
129        self.execute_query_with_options(query, params, options, context).await
130    }
131}