use chrono::Utc;
use std::sync::Arc;
use uuid::Uuid;
use crate::web::error::{WebError, WebResult};
use crate::web::models::metadata::{
AddFavoriteRequest, AddHistoryRequest, FavoriteItem, HistoryItem, UpdateFavoriteRequest,
};
use crate::web::storage::{MetadataStorage, SqliteStorage};
pub struct MetadataService {
storage: Arc<SqliteStorage>,
}
impl MetadataService {
pub fn new(storage: Arc<SqliteStorage>) -> Self {
Self { storage }
}
pub async fn add_history(
&self,
session_id: &str,
request: AddHistoryRequest,
) -> WebResult<HistoryItem> {
let item = HistoryItem {
id: Uuid::new_v4().to_string(),
session_id: session_id.to_string(),
query: request.query,
executed_at: Utc::now(),
execution_time_ms: request.execution_time_ms,
rows_returned: request.rows_returned,
success: request.success,
error_message: request.error_message,
};
self.storage.add_history(&item).await?;
Ok(item)
}
pub async fn get_history(
&self,
session_id: &str,
limit: usize,
offset: usize,
) -> WebResult<(Vec<HistoryItem>, i64)> {
self.storage.get_history(session_id, limit, offset).await
}
pub async fn delete_history(&self, id: &str, session_id: &str) -> WebResult<()> {
self.storage.delete_history(id, session_id).await
}
pub async fn clear_history(&self, session_id: &str) -> WebResult<()> {
self.storage.clear_history(session_id).await
}
pub async fn add_favorite(
&self,
session_id: &str,
request: AddFavoriteRequest,
) -> WebResult<FavoriteItem> {
if request.name.trim().is_empty() {
return Err(WebError::BadRequest(
"Favorite name cannot be empty".to_string(),
));
}
if request.query.trim().is_empty() {
return Err(WebError::BadRequest("Query cannot be empty".to_string()));
}
let item = FavoriteItem {
id: Uuid::new_v4().to_string(),
session_id: session_id.to_string(),
name: request.name,
query: request.query,
description: request.description,
created_at: Utc::now(),
};
self.storage.add_favorite(&item).await?;
Ok(item)
}
pub async fn get_favorites(&self, session_id: &str) -> WebResult<Vec<FavoriteItem>> {
self.storage.get_favorites(session_id).await
}
pub async fn get_favorite(&self, id: &str, session_id: &str) -> WebResult<FavoriteItem> {
self.storage.get_favorite(id, session_id).await
}
pub async fn update_favorite(
&self,
id: &str,
session_id: &str,
request: UpdateFavoriteRequest,
) -> WebResult<FavoriteItem> {
let mut item = self.storage.get_favorite(id, session_id).await?;
if let Some(name) = request.name {
if name.trim().is_empty() {
return Err(WebError::BadRequest(
"Favorite name cannot be empty".to_string(),
));
}
item.name = name;
}
if let Some(query) = request.query {
if query.trim().is_empty() {
return Err(WebError::BadRequest("Query cannot be empty".to_string()));
}
item.query = query;
}
if request.description.is_some() {
item.description = request.description;
}
self.storage.update_favorite(id, session_id, &item).await?;
Ok(item)
}
pub async fn delete_favorite(&self, id: &str, session_id: &str) -> WebResult<()> {
self.storage.delete_favorite(id, session_id).await
}
pub async fn delete_all_favorites(&self, session_id: &str) -> WebResult<()> {
self.storage.delete_all_favorites(session_id).await
}
}