Skip to main content

mxr_store/
search.rs

1use mxr_core::id::*;
2use mxr_core::types::*;
3
4impl super::Store {
5    pub async fn insert_saved_search(&self, search: &SavedSearch) -> Result<(), sqlx::Error> {
6        let id = search.id.as_str();
7        let account_id = search.account_id.as_ref().map(|id| id.as_str());
8        let sort = serde_json::to_string(&search.sort).unwrap();
9        let created_at = search.created_at.timestamp();
10        let position = search.position as i64; // i32 -> i64 for SQLite binding
11
12        sqlx::query!(
13            "INSERT INTO saved_searches (id, account_id, name, query, sort_order, icon, position, created_at)
14             VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
15            id,
16            account_id,
17            search.name,
18            search.query,
19            sort,
20            search.icon,
21            position,
22            created_at,
23        )
24        .execute(self.writer())
25        .await?;
26
27        Ok(())
28    }
29
30    pub async fn list_saved_searches(&self) -> Result<Vec<SavedSearch>, sqlx::Error> {
31        let rows = sqlx::query!(
32            r#"SELECT id as "id!", account_id, name as "name!", query as "query!",
33                      sort_order as "sort_order!", icon, position as "position!",
34                      created_at as "created_at!"
35               FROM saved_searches ORDER BY position ASC"#
36        )
37        .fetch_all(self.reader())
38        .await?;
39
40        Ok(rows
41            .into_iter()
42            .map(|r| SavedSearch {
43                id: SavedSearchId::from_uuid(uuid::Uuid::parse_str(&r.id).unwrap()),
44                account_id: r
45                    .account_id
46                    .map(|s| AccountId::from_uuid(uuid::Uuid::parse_str(&s).unwrap())),
47                name: r.name,
48                query: r.query,
49                sort: serde_json::from_str(&r.sort_order).unwrap_or(SortOrder::DateDesc),
50                icon: r.icon,
51                position: r.position as i32,
52                created_at: chrono::DateTime::from_timestamp(r.created_at, 0).unwrap_or_default(),
53            })
54            .collect())
55    }
56
57    pub async fn delete_saved_search(&self, id: &SavedSearchId) -> Result<(), sqlx::Error> {
58        let id_str = id.as_str();
59        sqlx::query!("DELETE FROM saved_searches WHERE id = ?", id_str)
60            .execute(self.writer())
61            .await?;
62        Ok(())
63    }
64
65    pub async fn get_saved_search_by_name(
66        &self,
67        name: &str,
68    ) -> Result<Option<SavedSearch>, sqlx::Error> {
69        let row = sqlx::query!(
70            r#"SELECT id as "id!", account_id, name as "name!", query as "query!",
71                      sort_order as "sort_order!", icon, position as "position!",
72                      created_at as "created_at!"
73               FROM saved_searches WHERE name = ?"#,
74            name,
75        )
76        .fetch_optional(self.reader())
77        .await?;
78
79        Ok(row.map(|r| SavedSearch {
80            id: SavedSearchId::from_uuid(uuid::Uuid::parse_str(&r.id).unwrap()),
81            account_id: r
82                .account_id
83                .map(|s| AccountId::from_uuid(uuid::Uuid::parse_str(&s).unwrap())),
84            name: r.name,
85            query: r.query,
86            sort: serde_json::from_str(&r.sort_order).unwrap_or(SortOrder::DateDesc),
87            icon: r.icon,
88            position: r.position as i32,
89            created_at: chrono::DateTime::from_timestamp(r.created_at, 0).unwrap_or_default(),
90        }))
91    }
92
93    pub async fn delete_saved_search_by_name(&self, name: &str) -> Result<bool, sqlx::Error> {
94        let result = sqlx::query!("DELETE FROM saved_searches WHERE name = ?", name)
95            .execute(self.writer())
96            .await?;
97        Ok(result.rows_affected() > 0)
98    }
99}