burncloud-database-impl 0.1.0

Database implementations for multiple backends (PostgreSQL, MySQL, SQLite, MongoDB) for BurnCloud
Documentation
#[cfg(feature = "mysql")]
use mysql_async::{Pool, Conn, prelude::Queryable, OptsBuilder};
use burncloud_database_core::{
    DatabaseConnection, QueryExecutor,
    TransactionManager, Transaction, QueryContext, QueryOptions, QueryResult, QueryParam
};
use burncloud_database_core::error::{DatabaseResult, DatabaseError};
use async_trait::async_trait;

#[cfg(feature = "mysql")]
pub struct MySQLConnection {
    pool: Option<Pool>,
    connection_string: String,
}

#[cfg(feature = "mysql")]
impl MySQLConnection {
    pub fn new(connection_string: String) -> Self {
        Self {
            pool: None,
            connection_string,
        }
    }
}

#[cfg(feature = "mysql")]
#[async_trait]
impl DatabaseConnection for MySQLConnection {
    async fn connect(&mut self) -> DatabaseResult<()> {
        let pool = Pool::new(&*self.connection_string);
        self.pool = Some(pool);
        Ok(())
    }

    async fn disconnect(&mut self) -> DatabaseResult<()> {
        if let Some(pool) = self.pool.take() {
            pool.disconnect().await
                .map_err(|e| DatabaseError::ConnectionFailed(e.to_string()))?;
        }
        Ok(())
    }

    async fn is_connected(&self) -> bool {
        self.pool.is_some()
    }

    async fn ping(&self) -> DatabaseResult<()> {
        if let Some(pool) = &self.pool {
            let mut conn = pool.get_conn().await
                .map_err(|e| DatabaseError::QueryFailed(e.to_string()))?;
            conn.ping().await
                .map_err(|e| DatabaseError::QueryFailed(e.to_string()))?;
            Ok(())
        } else {
            Err(DatabaseError::ConnectionFailed("Not connected".to_string()))
        }
    }
}

#[cfg(feature = "mysql")]
#[async_trait]
impl QueryExecutor for MySQLConnection {
    async fn execute_query(
        &self,
        _query: &str,
        _params: &[&dyn QueryParam],
        _context: &QueryContext,
    ) -> DatabaseResult<QueryResult> {
        Ok(QueryResult {
            rows: Vec::new(),
            rows_affected: 0,
            last_insert_id: None,
        })
    }

    async fn execute_query_with_options(
        &self,
        query: &str,
        params: &[&dyn QueryParam],
        _options: &QueryOptions,
        context: &QueryContext,
    ) -> DatabaseResult<QueryResult> {
        self.execute_query(query, params, context).await
    }
}

#[cfg(feature = "mysql")]
pub struct MySQLTransaction {
    // Simplified for example
}

#[cfg(feature = "mysql")]
#[async_trait]
impl Transaction for MySQLTransaction {
    async fn commit(self) -> DatabaseResult<()> {
        Ok(())
    }

    async fn rollback(self) -> DatabaseResult<()> {
        Ok(())
    }

    async fn execute_query(
        &self,
        _query: &str,
        _params: &[&dyn QueryParam],
    ) -> DatabaseResult<QueryResult> {
        Ok(QueryResult {
            rows: Vec::new(),
            rows_affected: 0,
            last_insert_id: None,
        })
    }
}

#[cfg(feature = "mysql")]
#[async_trait]
impl TransactionManager for MySQLConnection {
    type Transaction = MySQLTransaction;

    async fn begin_transaction(&self, _context: &QueryContext) -> DatabaseResult<Self::Transaction> {
        Ok(MySQLTransaction {})
    }
}