1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Password cache operations for archive extraction.
use crate::error::DatabaseError;
use crate::types::DownloadId;
use crate::{Error, Result};
use super::Database;
impl Database {
/// Cache a correct password for a download
///
/// This is used after successfully extracting an archive with a password,
/// so if the download needs to be reprocessed, we can try this password first.
pub async fn set_correct_password(
&self,
download_id: DownloadId,
password: &str,
) -> Result<()> {
sqlx::query(
r#"
INSERT INTO passwords (download_id, correct_password)
VALUES (?, ?)
ON CONFLICT(download_id) DO UPDATE SET correct_password = excluded.correct_password
"#,
)
.bind(download_id)
.bind(password)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to set correct password: {}",
e
)))
})?;
Ok(())
}
/// Get the cached correct password for a download
///
/// Returns None if no password is cached for this download.
pub async fn get_cached_password(&self, download_id: DownloadId) -> Result<Option<String>> {
let password: Option<String> =
sqlx::query_scalar("SELECT correct_password FROM passwords WHERE download_id = ?")
.bind(download_id)
.fetch_optional(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to get cached password: {}",
e
)))
})?;
Ok(password)
}
/// Delete cached password for a download
///
/// Note: This is automatically deleted via CASCADE when the download is deleted.
pub async fn delete_cached_password(&self, download_id: DownloadId) -> Result<()> {
sqlx::query("DELETE FROM passwords WHERE download_id = ?")
.bind(download_id)
.execute(&self.pool)
.await
.map_err(|e| {
Error::Database(DatabaseError::QueryFailed(format!(
"Failed to delete cached password: {}",
e
)))
})?;
Ok(())
}
}