Skip to main content

mxr_store/
search.rs

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