burncloud-database-impl 0.1.0

Database implementations for multiple backends (PostgreSQL, MySQL, SQLite, MongoDB) for BurnCloud
Documentation
#[cfg(feature = "sqlite")]
use rusqlite::{Connection, params};
use burncloud_database_core::{
    DatabaseConnection, QueryExecutor,
    TransactionManager, Transaction, QueryContext, QueryOptions, QueryResult, QueryParam
};
use burncloud_database_core::error::{DatabaseResult, DatabaseError};
use async_trait::async_trait;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[cfg(feature = "sqlite")]
pub struct SQLiteConnection {
    connection: Option<Arc<Mutex<Connection>>>,
    database_path: String,
}

#[cfg(feature = "sqlite")]
impl SQLiteConnection {
    pub fn new(database_path: String) -> Self {
        Self {
            connection: None,
            database_path,
        }
    }
}

#[cfg(feature = "sqlite")]
#[async_trait]
impl DatabaseConnection for SQLiteConnection {
    async fn connect(&mut self) -> DatabaseResult<()> {
        let conn = Connection::open(&self.database_path)
            .map_err(|e| DatabaseError::ConnectionFailed(e.to_string()))?;

        self.connection = Some(Arc::new(Mutex::new(conn)));
        Ok(())
    }

    async fn disconnect(&mut self) -> DatabaseResult<()> {
        self.connection = None;
        Ok(())
    }

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

    async fn ping(&self) -> DatabaseResult<()> {
        if let Some(conn) = &self.connection {
            let conn = conn.lock().unwrap();
            conn.execute("SELECT 1", [])
                .map_err(|e| DatabaseError::QueryFailed(e.to_string()))?;
            Ok(())
        } else {
            Err(DatabaseError::ConnectionFailed("Not connected".to_string()))
        }
    }
}

#[cfg(feature = "sqlite")]
#[async_trait]
impl QueryExecutor for SQLiteConnection {
    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 = "sqlite")]
pub struct SQLiteTransaction {
    // Simplified for example
}

#[cfg(feature = "sqlite")]
#[async_trait]
impl Transaction for SQLiteTransaction {
    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 = "sqlite")]
#[async_trait]
impl TransactionManager for SQLiteConnection {
    type Transaction = SQLiteTransaction;

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