Skip to main content

linkrs_server/web/services/
metadata_service.rs

1//! Metadata Service
2
3use chrono::Utc;
4use std::sync::Arc;
5use uuid::Uuid;
6
7use crate::web::error::{WebError, WebResult};
8use crate::web::models::metadata::{
9    AddFavoriteRequest, AddHistoryRequest, FavoriteItem, HistoryItem, UpdateFavoriteRequest,
10};
11use crate::web::storage::{MetadataStorage, SqliteStorage};
12
13/// Metadata service for query history and favorites
14pub struct MetadataService {
15    storage: Arc<SqliteStorage>,
16}
17
18impl MetadataService {
19    /// Create a new metadata service
20    pub fn new(storage: Arc<SqliteStorage>) -> Self {
21        Self { storage }
22    }
23
24    /// Add a query history item
25    pub async fn add_history(
26        &self,
27        session_id: &str,
28        request: AddHistoryRequest,
29    ) -> WebResult<HistoryItem> {
30        let item = HistoryItem {
31            id: Uuid::new_v4().to_string(),
32            session_id: session_id.to_string(),
33            query: request.query,
34            executed_at: Utc::now(),
35            execution_time_ms: request.execution_time_ms,
36            rows_returned: request.rows_returned,
37            success: request.success,
38            error_message: request.error_message,
39        };
40
41        self.storage.add_history(&item).await?;
42        Ok(item)
43    }
44
45    /// Get query history for a session
46    pub async fn get_history(
47        &self,
48        session_id: &str,
49        limit: usize,
50        offset: usize,
51    ) -> WebResult<(Vec<HistoryItem>, i64)> {
52        self.storage.get_history(session_id, limit, offset).await
53    }
54
55    /// Delete a history item
56    pub async fn delete_history(&self, id: &str, session_id: &str) -> WebResult<()> {
57        self.storage.delete_history(id, session_id).await
58    }
59
60    /// Clear all history for a session
61    pub async fn clear_history(&self, session_id: &str) -> WebResult<()> {
62        self.storage.clear_history(session_id).await
63    }
64
65    /// Add a favorite
66    pub async fn add_favorite(
67        &self,
68        session_id: &str,
69        request: AddFavoriteRequest,
70    ) -> WebResult<FavoriteItem> {
71        // Validate name is not empty
72        if request.name.trim().is_empty() {
73            return Err(WebError::BadRequest(
74                "Favorite name cannot be empty".to_string(),
75            ));
76        }
77
78        // Validate query is not empty
79        if request.query.trim().is_empty() {
80            return Err(WebError::BadRequest("Query cannot be empty".to_string()));
81        }
82
83        let item = FavoriteItem {
84            id: Uuid::new_v4().to_string(),
85            session_id: session_id.to_string(),
86            name: request.name,
87            query: request.query,
88            description: request.description,
89            created_at: Utc::now(),
90        };
91
92        self.storage.add_favorite(&item).await?;
93        Ok(item)
94    }
95
96    /// Get all favorites for a session
97    pub async fn get_favorites(&self, session_id: &str) -> WebResult<Vec<FavoriteItem>> {
98        self.storage.get_favorites(session_id).await
99    }
100
101    /// Get a favorite by ID
102    pub async fn get_favorite(&self, id: &str, session_id: &str) -> WebResult<FavoriteItem> {
103        self.storage.get_favorite(id, session_id).await
104    }
105
106    /// Update a favorite
107    pub async fn update_favorite(
108        &self,
109        id: &str,
110        session_id: &str,
111        request: UpdateFavoriteRequest,
112    ) -> WebResult<FavoriteItem> {
113        // Get existing favorite
114        let mut item = self.storage.get_favorite(id, session_id).await?;
115
116        // Update fields if provided
117        if let Some(name) = request.name {
118            if name.trim().is_empty() {
119                return Err(WebError::BadRequest(
120                    "Favorite name cannot be empty".to_string(),
121                ));
122            }
123            item.name = name;
124        }
125
126        if let Some(query) = request.query {
127            if query.trim().is_empty() {
128                return Err(WebError::BadRequest("Query cannot be empty".to_string()));
129            }
130            item.query = query;
131        }
132
133        if request.description.is_some() {
134            item.description = request.description;
135        }
136
137        self.storage.update_favorite(id, session_id, &item).await?;
138        Ok(item)
139    }
140
141    /// Delete a favorite
142    pub async fn delete_favorite(&self, id: &str, session_id: &str) -> WebResult<()> {
143        self.storage.delete_favorite(id, session_id).await
144    }
145
146    /// Delete all favorites for a session
147    pub async fn delete_all_favorites(&self, session_id: &str) -> WebResult<()> {
148        self.storage.delete_all_favorites(session_id).await
149    }
150}