revolt_database/models/files/ops/
reference.rs1use revolt_result::Result;
2
3use crate::File;
4use crate::FileUsedFor;
5use crate::ReferenceDb;
6
7use super::AbstractAttachments;
8
9#[async_trait]
10impl AbstractAttachments for ReferenceDb {
11 async fn insert_attachment(&self, attachment: &File) -> Result<()> {
13 let mut attachments = self.files.lock().await;
14 if attachments.contains_key(&attachment.id) {
15 Err(create_database_error!("insert", "attachment"))
16 } else {
17 attachments.insert(attachment.id.to_string(), attachment.clone());
18 Ok(())
19 }
20 }
21
22 async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result<File> {
24 let files = self.files.lock().await;
25 if let Some(file) = files.get(file_id) {
26 if file.tag == tag {
27 Ok(file.clone())
28 } else {
29 Err(create_error!(NotFound))
30 }
31 } else {
32 Err(create_error!(NotFound))
33 }
34 }
35
36 async fn fetch_deleted_attachments(&self) -> Result<Vec<File>> {
38 let files = self.files.lock().await;
39 Ok(files
40 .values()
41 .filter(|file| {
42 file.deleted.is_some_and(|v| v)
44 && !file.reported.is_some_and(|v| v)
46 })
47 .cloned()
48 .collect())
49 }
50
51 async fn fetch_dangling_files(&self) -> Result<Vec<File>> {
53 let files = self.files.lock().await;
54 Ok(files
55 .values()
56 .filter(|file| file.used_for.is_none() && !file.deleted.is_some_and(|v| v))
57 .cloned()
58 .collect())
59 }
60
61 async fn count_file_hash_references(&self, hash: &str) -> Result<usize> {
63 let files = self.files.lock().await;
64 Ok(files
65 .values()
66 .filter(|file| file.hash.as_ref().is_some_and(|h| h == hash))
67 .cloned()
68 .count())
69 }
70
71 async fn find_and_use_attachment(
73 &self,
74 id: &str,
75 tag: &str,
76 used_for: FileUsedFor,
77 uploader_id: String,
78 ) -> Result<File> {
79 let mut files = self.files.lock().await;
80 if let Some(file) = files.get_mut(id) {
81 if file.tag == tag {
82 file.uploader_id = Some(uploader_id);
83 file.used_for = Some(used_for);
84
85 Ok(file.clone())
86 } else {
87 Err(create_error!(NotFound))
88 }
89 } else {
90 Err(create_error!(NotFound))
91 }
92 }
93
94 async fn mark_attachment_as_reported(&self, id: &str) -> Result<()> {
96 let mut files = self.files.lock().await;
97 if let Some(file) = files.get_mut(id) {
98 file.reported = Some(true);
99 Ok(())
100 } else {
101 Err(create_error!(NotFound))
102 }
103 }
104
105 async fn mark_attachment_as_deleted(&self, id: &str) -> Result<()> {
107 let mut files = self.files.lock().await;
108 if let Some(file) = files.get_mut(id) {
109 file.deleted = Some(true);
110 Ok(())
111 } else {
112 Err(create_error!(NotFound))
113 }
114 }
115
116 async fn mark_attachments_as_deleted(&self, ids: &[String]) -> Result<()> {
118 let mut files = self.files.lock().await;
119
120 for id in ids {
121 if !files.contains_key(id) {
122 return Err(create_error!(NotFound));
123 }
124 }
125
126 for id in ids {
127 if let Some(file) = files.get_mut(id) {
128 file.reported = Some(true);
129 }
130 }
131
132 Ok(())
133 }
134
135 async fn delete_attachment(&self, id: &str) -> Result<()> {
137 let mut files = self.files.lock().await;
138 if files.remove(id).is_some() {
139 Ok(())
140 } else {
141 Err(create_error!(NotFound))
142 }
143 }
144}