use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::domain::entity::StoredFile;
use crate::infrastructure::persistence::{StoredFileRepository, PaginationParams, PaginatedResult, StoredFileFilter};
use super::QueryHandler;
#[deprecated(since = "0.2.0", note = "Use QueryHandler<Q> trait instead")]
#[async_trait]
pub trait StoredFileQuery: Send + Sync {
type Output;
async fn execute(&self) -> Result<Self::Output>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetStoredFileByIdQuery {
pub id: String,
}
pub struct GetStoredFileByIdHandler<R: StoredFileRepository> {
repository: std::sync::Arc<R>,
}
impl<R: StoredFileRepository> GetStoredFileByIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: StoredFileRepository + 'static> QueryHandler<GetStoredFileByIdQuery> for GetStoredFileByIdHandler<R> {
type Output = Option<StoredFile>;
async fn handle(&self, query: GetStoredFileByIdQuery) -> Result<Self::Output> {
self.repository.find_by_id(&query.id).await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListStoredFileQuery {
pub page: u32,
pub per_page: u32,
pub filter_bucket_id: Option<Uuid>,
pub filter_owner_id: Option<Uuid>,
pub filter_path: Option<String>,
pub filter_original_name: Option<String>,
pub filter_size_bytes: Option<i64>,
pub filter_mime_type: Option<String>,
pub filter_checksum: Option<String>,
pub filter_is_compressed: Option<bool>,
pub filter_original_size: Option<i64>,
pub filter_compression_algorithm: Option<String>,
pub filter_is_scanned: Option<bool>,
pub filter_threat_level: Option<ThreatLevel>,
pub filter_has_thumbnail: Option<bool>,
pub filter_thumbnail_path: Option<String>,
pub filter_has_video_thumbnail: Option<bool>,
pub filter_has_document_preview: Option<bool>,
pub filter_processing_status: Option<ProcessingStatus>,
pub filter_content_hash_id: Option<Uuid>,
pub filter_cdn_url: Option<String>,
pub filter_owner_module: Option<String>,
pub filter_owner_entity: Option<String>,
pub filter_owner_entity_id: Option<Uuid>,
pub filter_field_name: Option<String>,
pub filter_status: Option<FileStatus>,
pub filter_storage_key: Option<String>,
pub filter_previous_version_id: Option<Uuid>,
}
impl Default for ListStoredFileQuery {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
filter_bucket_id: None,
filter_owner_id: None,
filter_path: None,
filter_original_name: None,
filter_size_bytes: None,
filter_mime_type: None,
filter_checksum: None,
filter_is_compressed: None,
filter_original_size: None,
filter_compression_algorithm: None,
filter_is_scanned: None,
filter_threat_level: None,
filter_has_thumbnail: None,
filter_thumbnail_path: None,
filter_has_video_thumbnail: None,
filter_has_document_preview: None,
filter_processing_status: None,
filter_content_hash_id: None,
filter_cdn_url: None,
filter_owner_module: None,
filter_owner_entity: None,
filter_owner_entity_id: None,
filter_field_name: None,
filter_status: None,
filter_storage_key: None,
filter_previous_version_id: None,
}
}
}
pub struct ListStoredFileHandler<R: StoredFileRepository> {
repository: std::sync::Arc<R>,
}
impl<R: StoredFileRepository> ListStoredFileHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: StoredFileRepository + 'static> QueryHandler<ListStoredFileQuery> for ListStoredFileHandler<R> {
type Output = PaginatedResult<StoredFile>;
async fn handle(&self, query: ListStoredFileQuery) -> Result<Self::Output> {
let params = PaginationParams::new(query.page, query.per_page);
let filters = StoredFileFilter {
bucket_id: query.filter_bucket_id.clone(),
owner_id: query.filter_owner_id.clone(),
path: query.filter_path.clone(),
original_name: query.filter_original_name.clone(),
size_bytes: query.filter_size_bytes.clone(),
mime_type: query.filter_mime_type.clone(),
checksum: query.filter_checksum.clone(),
is_compressed: query.filter_is_compressed.clone(),
original_size: query.filter_original_size.clone(),
compression_algorithm: query.filter_compression_algorithm.clone(),
is_scanned: query.filter_is_scanned.clone(),
threat_level: query.filter_threat_level.clone(),
has_thumbnail: query.filter_has_thumbnail.clone(),
thumbnail_path: query.filter_thumbnail_path.clone(),
has_video_thumbnail: query.filter_has_video_thumbnail.clone(),
has_document_preview: query.filter_has_document_preview.clone(),
processing_status: query.filter_processing_status.clone(),
content_hash_id: query.filter_content_hash_id.clone(),
cdn_url: query.filter_cdn_url.clone(),
owner_module: query.filter_owner_module.clone(),
owner_entity: query.filter_owner_entity.clone(),
owner_entity_id: query.filter_owner_entity_id.clone(),
field_name: query.filter_field_name.clone(),
status: query.filter_status.clone(),
storage_key: query.filter_storage_key.clone(),
previous_version_id: query.filter_previous_version_id.clone(),
..Default::default()
};
if filters.has_filters() {
self.repository.list_with_filters(params, filters).await
} else {
self.repository.list(params).await
}
}
}