use crate::error::DatabaseError;
use crate::{Error, Result};
use super::{
Database, InsertRssFeedParams, InsertRssFilterParams, RssFeed, RssFilterRow,
UpdateRssFeedParams,
};
impl Database {
pub async fn get_all_rss_feeds(&self) -> Result<Vec<RssFeed>> {
let feeds = sqlx::query_as::<_, RssFeed>(
r#"
SELECT id, name, url, check_interval_secs, category, auto_download,
priority, enabled, last_check, last_error, created_at
FROM rss_feeds
ORDER BY id ASC
"#,
)
.fetch_all(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to get RSS feeds: {}",
e
)))
})?;
Ok(feeds)
}
pub async fn get_rss_feed(&self, id: i64) -> Result<Option<RssFeed>> {
let feed = sqlx::query_as::<_, RssFeed>(
r#"
SELECT id, name, url, check_interval_secs, category, auto_download,
priority, enabled, last_check, last_error, created_at
FROM rss_feeds
WHERE id = ?
"#,
)
.bind(id)
.fetch_optional(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to get RSS feed: {}",
e
)))
})?;
Ok(feed)
}
pub async fn insert_rss_feed(&self, params: InsertRssFeedParams<'_>) -> Result<i64> {
let InsertRssFeedParams {
name,
url,
check_interval_secs,
category,
auto_download,
priority,
enabled,
} = params;
let now = chrono::Utc::now().timestamp();
let result = sqlx::query(
r#"
INSERT INTO rss_feeds (name, url, check_interval_secs, category, auto_download,
priority, enabled, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
"#,
)
.bind(name)
.bind(url)
.bind(check_interval_secs)
.bind(category)
.bind(auto_download as i32)
.bind(priority)
.bind(enabled as i32)
.bind(now)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to insert RSS feed: {}",
e
)))
})?;
Ok(result.last_insert_rowid())
}
pub async fn update_rss_feed(&self, params: UpdateRssFeedParams<'_>) -> Result<bool> {
let UpdateRssFeedParams {
id,
name,
url,
check_interval_secs,
category,
auto_download,
priority,
enabled,
} = params;
let result = sqlx::query(
r#"
UPDATE rss_feeds
SET name = ?, url = ?, check_interval_secs = ?, category = ?,
auto_download = ?, priority = ?, enabled = ?
WHERE id = ?
"#,
)
.bind(name)
.bind(url)
.bind(check_interval_secs)
.bind(category)
.bind(auto_download as i32)
.bind(priority)
.bind(enabled as i32)
.bind(id)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to update RSS feed: {}",
e
)))
})?;
Ok(result.rows_affected() > 0)
}
pub async fn delete_rss_feed(&self, id: i64) -> Result<bool> {
let result = sqlx::query("DELETE FROM rss_feeds WHERE id = ?")
.bind(id)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to delete RSS feed: {}",
e
)))
})?;
Ok(result.rows_affected() > 0)
}
pub async fn get_rss_filters(&self, feed_id: i64) -> Result<Vec<RssFilterRow>> {
let filters = sqlx::query_as::<_, RssFilterRow>(
r#"
SELECT id, feed_id, name, include_patterns, exclude_patterns,
min_size, max_size, max_age_secs
FROM rss_filters
WHERE feed_id = ?
ORDER BY id ASC
"#,
)
.bind(feed_id)
.fetch_all(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to get RSS filters: {}",
e
)))
})?;
Ok(filters)
}
pub async fn insert_rss_filter(&self, params: InsertRssFilterParams<'_>) -> Result<i64> {
let InsertRssFilterParams {
feed_id,
name,
include_patterns,
exclude_patterns,
min_size,
max_size,
max_age_secs,
} = params;
let result = sqlx::query(
r#"
INSERT INTO rss_filters (feed_id, name, include_patterns, exclude_patterns,
min_size, max_size, max_age_secs)
VALUES (?, ?, ?, ?, ?, ?, ?)
"#,
)
.bind(feed_id)
.bind(name)
.bind(include_patterns)
.bind(exclude_patterns)
.bind(min_size)
.bind(max_size)
.bind(max_age_secs)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to insert RSS filter: {}",
e
)))
})?;
Ok(result.last_insert_rowid())
}
pub async fn delete_rss_filters(&self, feed_id: i64) -> Result<()> {
sqlx::query("DELETE FROM rss_filters WHERE feed_id = ?")
.bind(feed_id)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to delete RSS filters: {}",
e
)))
})?;
Ok(())
}
pub async fn update_rss_feed_check_status(
&self,
id: i64,
last_error: Option<&str>,
) -> Result<()> {
let now = chrono::Utc::now().timestamp();
sqlx::query(
r#"
UPDATE rss_feeds
SET last_check = ?, last_error = ?
WHERE id = ?
"#,
)
.bind(now)
.bind(last_error)
.bind(id)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to update RSS feed status: {}",
e
)))
})?;
Ok(())
}
}