Skip to main content

max / balanced_breakfast

2.8 KB · 88 lines History Blame Raw
1 use super::{
2 CreateQueryFeed, DbQueryFeed, QueryCondition, QueryFeedId, SqlitePool, TIMESTAMP_FMT, Utc,
3 };
4
5 #[derive(Clone)]
6 /// Repository for saved query feed (virtual source) CRUD
7 pub struct QueryFeedsRepository {
8 pool: SqlitePool,
9 }
10
11 impl QueryFeedsRepository {
12 #[tracing::instrument(skip_all)]
13 pub fn new(pool: SqlitePool) -> Self {
14 Self { pool }
15 }
16
17 /// Insert a new query feed and return the created row.
18 pub async fn create(&self, input: CreateQueryFeed) -> Result<DbQueryFeed, sqlx::Error> {
19 let id = QueryFeedId::new();
20 let now = Utc::now().format(TIMESTAMP_FMT).to_string();
21 let rules_json = serde_json::to_string(&input.rules).unwrap_or_else(|_| "[]".to_string());
22
23 sqlx::query_as(
24 r"
25 INSERT INTO query_feeds (id, name, rules, created_at, updated_at)
26 VALUES (?1, ?2, ?3, ?4, ?4)
27 RETURNING *
28 ",
29 )
30 .bind(id)
31 .bind(&input.name)
32 .bind(&rules_json)
33 .bind(&now)
34 .fetch_one(&self.pool)
35 .await
36 }
37
38 /// Look up a single query feed by ID. Returns `None` if not found.
39 #[tracing::instrument(skip_all)]
40 pub async fn get(&self, id: QueryFeedId) -> Result<Option<DbQueryFeed>, sqlx::Error> {
41 sqlx::query_as("SELECT * FROM query_feeds WHERE id = ?1")
42 .bind(id)
43 .fetch_optional(&self.pool)
44 .await
45 }
46
47 /// List all query feeds, ordered by name.
48 #[tracing::instrument(skip_all)]
49 pub async fn list_all(&self) -> Result<Vec<DbQueryFeed>, sqlx::Error> {
50 sqlx::query_as("SELECT * FROM query_feeds ORDER BY name")
51 .fetch_all(&self.pool)
52 .await
53 }
54
55 /// Update a query feed's name and rules.
56 #[tracing::instrument(skip_all)]
57 pub async fn update(
58 &self,
59 id: QueryFeedId,
60 name: &str,
61 rules: &[QueryCondition],
62 ) -> Result<(), sqlx::Error> {
63 let now = Utc::now().format(TIMESTAMP_FMT).to_string();
64 let rules_json = serde_json::to_string(rules).unwrap_or_else(|_| "[]".to_string());
65
66 sqlx::query("UPDATE query_feeds SET name = ?1, rules = ?2, updated_at = ?3 WHERE id = ?4")
67 .bind(name)
68 .bind(&rules_json)
69 .bind(&now)
70 .bind(id)
71 .execute(&self.pool)
72 .await?;
73 Ok(())
74 }
75
76 /// Delete a query feed by ID.
77 #[tracing::instrument(skip_all)]
78 pub async fn delete(&self, id: QueryFeedId) -> Result<(), sqlx::Error> {
79 sqlx::query("DELETE FROM query_feeds WHERE id = ?1")
80 .bind(id)
81 .execute(&self.pool)
82 .await?;
83 Ok(())
84 }
85 }
86
87 // ── BookmarksRepository ──────────────────────────────────────────
88