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;
pub struct BurnCloudDatabase {
pub client: Arc<DatabaseClient>,
pub pool: Arc<DatabasePool>,
pub migration_manager: Arc<DatabaseMigrationManager>,
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 {
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));
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, ¶ms, 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, ¶ms, 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>,
}
#[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>,
}
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()
}
}