burncloud-database-client 0.1.1

High-level database client with migrations, pooling, and AI model management for BurnCloud
Documentation
// BurnCloud数据库管理器 - 统一的数据库操作接口

use crate::migration::MigrationManager as DatabaseMigrationManager;
use crate::*;
use burncloud_database_core::error::{DatabaseResult, DatabaseError};
use burncloud_database_core::{DatabaseConfig, QueryContext};
use std::sync::Arc;

/// BurnCloud数据库管理器
/// 提供统一的数据库操作接口,包含所有业务相关的Repository
pub struct BurnCloudDatabase {
    // 基础组件
    pub client: Arc<DatabaseClient>,
    pub pool: Arc<DatabasePool>,
    pub migration_manager: Arc<DatabaseMigrationManager>,

    // 业务Repository
    pub ai_models: Arc<AiModelRepository>,
    pub deployments: Arc<ModelDeploymentRepository>,
    pub system_metrics: Arc<SystemMetricsRepository>,
    pub model_metrics: Arc<ModelMetricsRepository>,
    pub request_logs: Arc<RequestLogRepository>,
    pub user_settings: Arc<UserSettingsRepository>,
    pub security_config: Arc<SecurityConfigRepository>,
}

impl BurnCloudDatabase {
    /// 创建新的BurnCloud数据库管理器
    pub async fn new(config: DatabaseConfig) -> DatabaseResult<Self> {
        // 创建数据库连接和执行器
        let connection = DatabaseClientFactory::create_connection(&config)?;
        let query_executor1 = DatabaseClientFactory::create_query_executor(&config)?;

        // 为每个组件创建独立的执行器
        let query_executor2 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor3 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor4 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor5 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor6 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor7 = DatabaseClientFactory::create_query_executor(&config)?;
        let query_executor8 = DatabaseClientFactory::create_query_executor(&config)?;

        // 创建客户端和连接池
        let client = Arc::new(DatabaseClient::new(connection, query_executor1));
        let pool = Arc::new(DatabasePool::new(config.clone(), config.pool_size.unwrap_or(10) as usize));

        // 连接数据库
        client.connect().await?;

        // 创建迁移管理器
        let migration_manager = Arc::new(DatabaseMigrationManager::new(query_executor2));

        // 创建所有Repository
        let ai_models = Arc::new(AiModelRepository::new(query_executor3));
        let deployments = Arc::new(ModelDeploymentRepository::new(query_executor4));
        let system_metrics = Arc::new(SystemMetricsRepository::new(query_executor5));
        let model_metrics = Arc::new(ModelMetricsRepository::new(query_executor6));
        let request_logs = Arc::new(RequestLogRepository::new(query_executor7));
        let user_settings = Arc::new(UserSettingsRepository::new(query_executor8));
        let security_config = Arc::new(SecurityConfigRepository::new(DatabaseClientFactory::create_query_executor(&config)?));

        Ok(Self {
            client,
            pool,
            migration_manager,
            ai_models,
            deployments,
            system_metrics,
            model_metrics,
            request_logs,
            user_settings,
            security_config,
        })
    }

    /// 初始化数据库(运行迁移)
    pub async fn initialize(&self) -> DatabaseResult<()> {
        let context = QueryContext::default();
        self.migration_manager.run_migrations(&context).await?;
        println!("✅ Database initialized successfully");
        Ok(())
    }

    /// 检查数据库连接状态
    pub async fn health_check(&self) -> DatabaseResult<()> {
        self.client.ping().await?;
        println!("✅ Database connection healthy");
        Ok(())
    }

    /// 获取数据库统计信息
    pub async fn get_database_stats(&self) -> DatabaseResult<DatabaseStats> {
        let context = QueryContext::default();

        // 获取各表的记录数
        let models_count = self.count_table_rows("ai_models", &context).await?;
        let deployments_count = self.count_table_rows("model_deployments", &context).await?;
        let metrics_count = self.count_table_rows("system_metrics", &context).await?;
        let logs_count = self.count_table_rows("request_logs", &context).await?;

        // 获取最新的系统指标
        let latest_system_metrics = self.system_metrics.get_latest(&context).await?;

        Ok(DatabaseStats {
            models_count,
            deployments_count,
            metrics_count,
            logs_count,
            latest_system_metrics,
            pool_size: self.pool.get_pool_size().await,
        })
    }

    /// 清理旧数据
    pub async fn cleanup_old_data(&self, retention_days: u32) -> DatabaseResult<CleanupStats> {
        let context = QueryContext::default();
        let cutoff_time = chrono::Utc::now() - chrono::Duration::days(retention_days as i64);

        // 清理旧的系统指标
        let metrics_deleted = self.system_metrics.cleanup_old_metrics(cutoff_time, &context).await?;

        // 清理旧的请求日志
        let logs_deleted = self.cleanup_old_logs(cutoff_time, &context).await?;

        Ok(CleanupStats {
            metrics_deleted,
            logs_deleted,
            cutoff_time,
        })
    }

    /// 备份数据库配置
    pub async fn backup_config(&self) -> DatabaseResult<BurnCloudConfig> {
        let context = QueryContext::default();

        // 获取所有模型
        let models = self.ai_models.base.find_all(&QueryOptions::default(), &context).await?;

        // 获取所有部署
        let deployments = self.deployments.base.find_all(&QueryOptions::default(), &context).await?;

        // 获取用户设置
        let user_settings = self.user_settings.base.find_all(&QueryOptions::default(), &context).await?;

        // 获取安全配置
        let security_config = self.security_config.get_current(&context).await?;

        Ok(BurnCloudConfig {
            models,
            deployments,
            user_settings,
            security_config,
            backup_time: chrono::Utc::now(),
        })
    }

    /// 恢复数据库配置
    pub async fn restore_config(&self, config: &BurnCloudConfig) -> DatabaseResult<()> {
        let context = QueryContext::default();

        // 注意:这是一个简化的恢复实现
        // 实际应用中需要更复杂的事务处理和冲突解决

        for model in &config.models {
            let _ = self.ai_models.base.create(model, &context).await;
        }

        for deployment in &config.deployments {
            let _ = self.deployments.base.create(deployment, &context).await;
        }

        for settings in &config.user_settings {
            let _ = self.user_settings.base.create(settings, &context).await;
        }

        if let Some(security) = &config.security_config {
            let _ = self.security_config.base.create(security, &context).await;
        }

        println!("✅ Configuration restored successfully");
        Ok(())
    }

    // 辅助方法
    async fn count_table_rows(&self, table_name: &str, context: &QueryContext) -> DatabaseResult<u64> {
        let query = format!("SELECT COUNT(*) as count FROM {}", table_name);
        let params: Vec<&dyn burncloud_database_core::QueryParam> = vec![];

        let result = self.client.execute_query(&query, &params, context).await?;

        if let Some(row) = result.rows.first() {
            if let Some(count_value) = row.get("count") {
                if let Some(count) = count_value.as_u64() {
                    return Ok(count);
                }
            }
        }

        Ok(0)
    }

    async fn cleanup_old_logs(&self, cutoff_time: chrono::DateTime<chrono::Utc>, context: &QueryContext) -> DatabaseResult<u64> {
        let query = "DELETE FROM request_logs WHERE timestamp < $1";
        let time_param = burncloud_database_impl::StringParam(cutoff_time.to_rfc3339());
        let params: Vec<&dyn burncloud_database_core::QueryParam> = vec![&time_param];

        let result = self.client.execute_query(query, &params, context).await?;
        Ok(result.rows_affected)
    }
}

/// 数据库统计信息
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct DatabaseStats {
    pub models_count: u64,
    pub deployments_count: u64,
    pub metrics_count: u64,
    pub logs_count: u64,
    pub latest_system_metrics: Option<SystemMetrics>,
    pub pool_size: usize,
}

/// 清理统计信息
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct CleanupStats {
    pub metrics_deleted: u64,
    pub logs_deleted: u64,
    pub cutoff_time: chrono::DateTime<chrono::Utc>,
}

/// BurnCloud配置备份
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct BurnCloudConfig {
    pub models: Vec<AiModel>,
    pub deployments: Vec<ModelDeployment>,
    pub user_settings: Vec<UserSettings>,
    pub security_config: Option<SecurityConfig>,
    pub backup_time: chrono::DateTime<chrono::Utc>,
}

/// BurnCloud数据库构建器
pub struct BurnCloudDatabaseBuilder {
    config: DatabaseConfig,
}

impl BurnCloudDatabaseBuilder {
    pub fn new() -> Self {
        Self {
            config: DatabaseConfig {
                database_type: burncloud_database_core::DatabaseType::Postgres,
                host: "localhost".to_string(),
                port: 5432,
                database: "burncloud".to_string(),
                username: "burncloud".to_string(),
                password: "password".to_string(),
                pool_size: Some(10),
                timeout: Some(30),
                ssl: Some(false),
            },
        }
    }

    pub fn with_postgres(mut self, host: &str, port: u16, database: &str, username: &str, password: &str) -> Self {
        self.config.database_type = burncloud_database_core::DatabaseType::Postgres;
        self.config.host = host.to_string();
        self.config.port = port;
        self.config.database = database.to_string();
        self.config.username = username.to_string();
        self.config.password = password.to_string();
        self
    }

    pub fn with_sqlite(mut self, database_path: &str) -> Self {
        self.config.database_type = burncloud_database_core::DatabaseType::SQLite;
        self.config.database = database_path.to_string();
        self
    }

    pub fn with_pool_size(mut self, size: u32) -> Self {
        self.config.pool_size = Some(size);
        self
    }

    pub fn with_timeout(mut self, timeout_seconds: u64) -> Self {
        self.config.timeout = Some(timeout_seconds);
        self
    }

    pub async fn build(self) -> DatabaseResult<BurnCloudDatabase> {
        BurnCloudDatabase::new(self.config).await
    }

    pub async fn build_and_initialize(self) -> DatabaseResult<BurnCloudDatabase> {
        let db = self.build().await?;
        db.initialize().await?;
        Ok(db)
    }
}

impl Default for BurnCloudDatabaseBuilder {
    fn default() -> Self {
        Self::new()
    }
}