1use crate::types::HistoryEntry;
4use crate::{Error, Result};
5
6use super::{Database, HistoryRow, NewHistoryEntry};
7
8impl Database {
9 pub async fn insert_history(&self, entry: &NewHistoryEntry) -> Result<i64> {
14 let result = sqlx::query(
15 r#"
16 INSERT INTO history (
17 name, category, destination, status, size_bytes,
18 download_time_secs, completed_at
19 )
20 VALUES (?, ?, ?, ?, ?, ?, ?)
21 "#,
22 )
23 .bind(&entry.name)
24 .bind(&entry.category)
25 .bind(
26 entry
27 .destination
28 .as_ref()
29 .and_then(|p| p.to_str().map(String::from)),
30 )
31 .bind(entry.status)
32 .bind(entry.size_bytes as i64)
33 .bind(entry.download_time_secs)
34 .bind(entry.completed_at)
35 .execute(&self.pool)
36 .await
37 .map_err(Error::Sqlx)?;
38
39 Ok(result.last_insert_rowid())
40 }
41
42 pub async fn query_history(
47 &self,
48 status_filter: Option<i32>,
49 limit: usize,
50 offset: usize,
51 ) -> Result<Vec<HistoryEntry>> {
52 let query = if let Some(status) = status_filter {
53 sqlx::query_as::<_, HistoryRow>(
54 r#"
55 SELECT id, name, category, destination, status, size_bytes,
56 download_time_secs, completed_at
57 FROM history
58 WHERE status = ?
59 ORDER BY completed_at DESC
60 LIMIT ? OFFSET ?
61 "#,
62 )
63 .bind(status)
64 .bind(limit as i64)
65 .bind(offset as i64)
66 } else {
67 sqlx::query_as::<_, HistoryRow>(
68 r#"
69 SELECT id, name, category, destination, status, size_bytes,
70 download_time_secs, completed_at
71 FROM history
72 ORDER BY completed_at DESC
73 LIMIT ? OFFSET ?
74 "#,
75 )
76 .bind(limit as i64)
77 .bind(offset as i64)
78 };
79
80 let rows = query.fetch_all(&self.pool).await.map_err(Error::Sqlx)?;
81
82 Ok(rows.into_iter().map(HistoryEntry::from).collect())
83 }
84
85 pub async fn count_history(&self, status_filter: Option<i32>) -> Result<i64> {
89 let count = if let Some(status) = status_filter {
90 sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM history WHERE status = ?")
91 .bind(status)
92 .fetch_one(&self.pool)
93 .await
94 .map_err(Error::Sqlx)?
95 } else {
96 sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM history")
97 .fetch_one(&self.pool)
98 .await
99 .map_err(Error::Sqlx)?
100 };
101
102 Ok(count)
103 }
104
105 pub async fn delete_history_before(&self, before_timestamp: i64) -> Result<u64> {
110 let result = sqlx::query("DELETE FROM history WHERE completed_at < ?")
111 .bind(before_timestamp)
112 .execute(&self.pool)
113 .await
114 .map_err(Error::Sqlx)?;
115
116 Ok(result.rows_affected())
117 }
118
119 pub async fn delete_history_by_status(&self, status: i32) -> Result<u64> {
124 let result = sqlx::query("DELETE FROM history WHERE status = ?")
125 .bind(status)
126 .execute(&self.pool)
127 .await
128 .map_err(Error::Sqlx)?;
129
130 Ok(result.rows_affected())
131 }
132
133 pub async fn clear_history(&self) -> Result<u64> {
138 let result = sqlx::query("DELETE FROM history")
139 .execute(&self.pool)
140 .await
141 .map_err(Error::Sqlx)?;
142
143 Ok(result.rows_affected())
144 }
145
146 pub async fn delete_history_filtered(
155 &self,
156 before_timestamp: Option<i64>,
157 status: Option<i32>,
158 ) -> Result<u64> {
159 match (before_timestamp, status) {
160 (None, None) => {
161 self.clear_history().await
163 }
164 (Some(before), None) => {
165 self.delete_history_before(before).await
167 }
168 (None, Some(status_val)) => {
169 self.delete_history_by_status(status_val).await
171 }
172 (Some(before), Some(status_val)) => {
173 let result =
175 sqlx::query("DELETE FROM history WHERE completed_at < ? AND status = ?")
176 .bind(before)
177 .bind(status_val)
178 .execute(&self.pool)
179 .await
180 .map_err(Error::Sqlx)?;
181
182 Ok(result.rows_affected())
183 }
184 }
185 }
186
187 pub async fn get_history_entry(&self, id: i64) -> Result<Option<HistoryEntry>> {
189 let row = sqlx::query_as::<_, HistoryRow>(
190 r#"
191 SELECT id, name, category, destination, status, size_bytes,
192 download_time_secs, completed_at
193 FROM history
194 WHERE id = ?
195 "#,
196 )
197 .bind(id)
198 .fetch_optional(&self.pool)
199 .await
200 .map_err(Error::Sqlx)?;
201
202 Ok(row.map(HistoryEntry::from))
203 }
204}