use crate::core::models::database::DatabaseMetadata;
use crate::core::models::field::Field;
use crate::core::models::{MetabaseId, SyncResult};
use crate::repository::database::{
DatabaseFilterParams, DatabaseRepository, HttpDatabaseRepository,
};
use crate::repository::traits::PaginationParams;
use crate::service::traits::{Service, ServiceError, ServiceResult};
use crate::transport::http_provider_safe::HttpProviderSafe;
use async_trait::async_trait;
use std::sync::Arc;
#[async_trait]
pub trait DatabaseService: Service + Send + Sync {
async fn get_database_metadata(&self, id: MetabaseId) -> ServiceResult<DatabaseMetadata>;
async fn sync_database_schema(&self, id: MetabaseId) -> ServiceResult<SyncResult>;
async fn get_database_fields(&self, id: MetabaseId) -> ServiceResult<Vec<Field>>;
async fn get_database_schemas(&self, id: MetabaseId) -> ServiceResult<Vec<String>>;
async fn list_databases(
&self,
pagination: Option<PaginationParams>,
filters: Option<DatabaseFilterParams>,
) -> ServiceResult<Vec<DatabaseMetadata>>;
async fn validate_database_id(&self, id: MetabaseId) -> ServiceResult<()>;
}
pub struct HttpDatabaseService {
repository: Arc<dyn DatabaseRepository>,
}
impl HttpDatabaseService {
pub fn new(repository: Arc<dyn DatabaseRepository>) -> Self {
Self { repository }
}
pub fn from_http_provider(http_provider: Arc<dyn HttpProviderSafe>) -> Self {
let repository = Arc::new(HttpDatabaseRepository::new(http_provider));
Self { repository }
}
}
#[async_trait]
impl Service for HttpDatabaseService {
fn name(&self) -> &str {
"DatabaseService"
}
}
#[async_trait]
impl DatabaseService for HttpDatabaseService {
async fn get_database_metadata(&self, id: MetabaseId) -> ServiceResult<DatabaseMetadata> {
self.validate_database_id(id).await?;
self.repository
.get(&id)
.await
.map_err(ServiceError::Repository)
}
async fn sync_database_schema(&self, id: MetabaseId) -> ServiceResult<SyncResult> {
self.validate_database_id(id).await?;
self.repository
.sync_database_schema(&id)
.await
.map_err(ServiceError::Repository)
}
async fn get_database_fields(&self, id: MetabaseId) -> ServiceResult<Vec<Field>> {
self.validate_database_id(id).await?;
self.repository
.get_database_fields(&id)
.await
.map_err(ServiceError::Repository)
}
async fn get_database_schemas(&self, id: MetabaseId) -> ServiceResult<Vec<String>> {
self.validate_database_id(id).await?;
self.repository
.get_database_schemas(&id)
.await
.map_err(ServiceError::Repository)
}
async fn list_databases(
&self,
pagination: Option<PaginationParams>,
filters: Option<DatabaseFilterParams>,
) -> ServiceResult<Vec<DatabaseMetadata>> {
self.repository
.list_with_filters(pagination, filters)
.await
.map_err(ServiceError::Repository)
}
async fn validate_database_id(&self, id: MetabaseId) -> ServiceResult<()> {
if id.0 < 1 {
return Err(ServiceError::Validation(
"Invalid database ID: must be positive".to_string(),
));
}
Ok(())
}
}