1use crate::error::DatabaseError;
4use crate::{Error, Result};
5
6use super::{
7 Database, InsertRssFeedParams, InsertRssFilterParams, RssFeed, RssFilterRow,
8 UpdateRssFeedParams,
9};
10
11impl Database {
12 pub async fn get_all_rss_feeds(&self) -> Result<Vec<RssFeed>> {
14 let feeds = sqlx::query_as::<_, RssFeed>(
15 r#"
16 SELECT id, name, url, check_interval_secs, category, auto_download,
17 priority, enabled, last_check, last_error, created_at
18 FROM rss_feeds
19 ORDER BY id ASC
20 "#,
21 )
22 .fetch_all(&self.pool)
23 .await
24 .map_err(|e| {
25 Error::Database(DatabaseError::QueryFailed(format!(
26 "Failed to get RSS feeds: {}",
27 e
28 )))
29 })?;
30
31 Ok(feeds)
32 }
33
34 pub async fn get_rss_feed(&self, id: i64) -> Result<Option<RssFeed>> {
36 let feed = sqlx::query_as::<_, RssFeed>(
37 r#"
38 SELECT id, name, url, check_interval_secs, category, auto_download,
39 priority, enabled, last_check, last_error, created_at
40 FROM rss_feeds
41 WHERE id = ?
42 "#,
43 )
44 .bind(id)
45 .fetch_optional(&self.pool)
46 .await
47 .map_err(|e| {
48 Error::Database(DatabaseError::QueryFailed(format!(
49 "Failed to get RSS feed: {}",
50 e
51 )))
52 })?;
53
54 Ok(feed)
55 }
56
57 pub async fn insert_rss_feed(&self, params: InsertRssFeedParams<'_>) -> Result<i64> {
59 let InsertRssFeedParams {
60 name,
61 url,
62 check_interval_secs,
63 category,
64 auto_download,
65 priority,
66 enabled,
67 } = params;
68 let now = chrono::Utc::now().timestamp();
69
70 let result = sqlx::query(
71 r#"
72 INSERT INTO rss_feeds (name, url, check_interval_secs, category, auto_download,
73 priority, enabled, created_at)
74 VALUES (?, ?, ?, ?, ?, ?, ?, ?)
75 "#,
76 )
77 .bind(name)
78 .bind(url)
79 .bind(check_interval_secs)
80 .bind(category)
81 .bind(auto_download as i32)
82 .bind(priority)
83 .bind(enabled as i32)
84 .bind(now)
85 .execute(&self.pool)
86 .await
87 .map_err(|e| {
88 Error::Database(DatabaseError::QueryFailed(format!(
89 "Failed to insert RSS feed: {}",
90 e
91 )))
92 })?;
93
94 Ok(result.last_insert_rowid())
95 }
96
97 pub async fn update_rss_feed(&self, params: UpdateRssFeedParams<'_>) -> Result<bool> {
99 let UpdateRssFeedParams {
100 id,
101 name,
102 url,
103 check_interval_secs,
104 category,
105 auto_download,
106 priority,
107 enabled,
108 } = params;
109 let result = sqlx::query(
110 r#"
111 UPDATE rss_feeds
112 SET name = ?, url = ?, check_interval_secs = ?, category = ?,
113 auto_download = ?, priority = ?, enabled = ?
114 WHERE id = ?
115 "#,
116 )
117 .bind(name)
118 .bind(url)
119 .bind(check_interval_secs)
120 .bind(category)
121 .bind(auto_download as i32)
122 .bind(priority)
123 .bind(enabled as i32)
124 .bind(id)
125 .execute(&self.pool)
126 .await
127 .map_err(|e| {
128 Error::Database(DatabaseError::QueryFailed(format!(
129 "Failed to update RSS feed: {}",
130 e
131 )))
132 })?;
133
134 Ok(result.rows_affected() > 0)
135 }
136
137 pub async fn delete_rss_feed(&self, id: i64) -> Result<bool> {
139 let result = sqlx::query("DELETE FROM rss_feeds WHERE id = ?")
140 .bind(id)
141 .execute(&self.pool)
142 .await
143 .map_err(|e| {
144 Error::Database(DatabaseError::QueryFailed(format!(
145 "Failed to delete RSS feed: {}",
146 e
147 )))
148 })?;
149
150 Ok(result.rows_affected() > 0)
151 }
152
153 pub async fn get_rss_filters(&self, feed_id: i64) -> Result<Vec<RssFilterRow>> {
155 let filters = sqlx::query_as::<_, RssFilterRow>(
156 r#"
157 SELECT id, feed_id, name, include_patterns, exclude_patterns,
158 min_size, max_size, max_age_secs
159 FROM rss_filters
160 WHERE feed_id = ?
161 ORDER BY id ASC
162 "#,
163 )
164 .bind(feed_id)
165 .fetch_all(&self.pool)
166 .await
167 .map_err(|e| {
168 Error::Database(DatabaseError::QueryFailed(format!(
169 "Failed to get RSS filters: {}",
170 e
171 )))
172 })?;
173
174 Ok(filters)
175 }
176
177 pub async fn insert_rss_filter(&self, params: InsertRssFilterParams<'_>) -> Result<i64> {
179 let InsertRssFilterParams {
180 feed_id,
181 name,
182 include_patterns,
183 exclude_patterns,
184 min_size,
185 max_size,
186 max_age_secs,
187 } = params;
188 let result = sqlx::query(
189 r#"
190 INSERT INTO rss_filters (feed_id, name, include_patterns, exclude_patterns,
191 min_size, max_size, max_age_secs)
192 VALUES (?, ?, ?, ?, ?, ?, ?)
193 "#,
194 )
195 .bind(feed_id)
196 .bind(name)
197 .bind(include_patterns)
198 .bind(exclude_patterns)
199 .bind(min_size)
200 .bind(max_size)
201 .bind(max_age_secs)
202 .execute(&self.pool)
203 .await
204 .map_err(|e| {
205 Error::Database(DatabaseError::QueryFailed(format!(
206 "Failed to insert RSS filter: {}",
207 e
208 )))
209 })?;
210
211 Ok(result.last_insert_rowid())
212 }
213
214 pub async fn delete_rss_filters(&self, feed_id: i64) -> Result<()> {
216 sqlx::query("DELETE FROM rss_filters WHERE feed_id = ?")
217 .bind(feed_id)
218 .execute(&self.pool)
219 .await
220 .map_err(|e| {
221 Error::Database(DatabaseError::QueryFailed(format!(
222 "Failed to delete RSS filters: {}",
223 e
224 )))
225 })?;
226
227 Ok(())
228 }
229
230 pub async fn update_rss_feed_check_status(
232 &self,
233 id: i64,
234 last_error: Option<&str>,
235 ) -> Result<()> {
236 let now = chrono::Utc::now().timestamp();
237
238 sqlx::query(
239 r#"
240 UPDATE rss_feeds
241 SET last_check = ?, last_error = ?
242 WHERE id = ?
243 "#,
244 )
245 .bind(now)
246 .bind(last_error)
247 .bind(id)
248 .execute(&self.pool)
249 .await
250 .map_err(|e| {
251 Error::Database(DatabaseError::QueryFailed(format!(
252 "Failed to update RSS feed status: {}",
253 e
254 )))
255 })?;
256
257 Ok(())
258 }
259}