mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 13:36:59 +00:00
feat: file deletion implementation
This commit is contained in:
@@ -15,4 +15,7 @@ pub trait AbstractAttachmentHashes: Sync + Send {
|
||||
|
||||
/// Update an attachment hash nonce value.
|
||||
async fn set_attachment_hash_nonce(&self, hash: &str, nonce: &str) -> Result<()>;
|
||||
|
||||
/// Delete attachment hash by id.
|
||||
async fn delete_attachment_hash(&self, id: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -48,4 +48,9 @@ impl AbstractAttachmentHashes for MongoDb {
|
||||
.map(|_| ())
|
||||
.map_err(|_| create_database_error!("update_one", COL))
|
||||
}
|
||||
|
||||
/// Delete attachment hash by id.
|
||||
async fn delete_attachment_hash(&self, id: &str) -> Result<()> {
|
||||
query!(self, delete_one_by_id, COL, id).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ impl AbstractAttachmentHashes for ReferenceDb {
|
||||
let hashes = self.file_hashes.lock().await;
|
||||
hashes
|
||||
.values()
|
||||
.find(|&hash| hash.id == hash_value || hash.processed_hash == hash_value)
|
||||
.cloned()
|
||||
.find(|hash| hash.id == hash_value || hash.processed_hash == hash_value)
|
||||
.ok_or(create_error!(NotFound))
|
||||
}
|
||||
|
||||
@@ -38,4 +38,14 @@ impl AbstractAttachmentHashes for ReferenceDb {
|
||||
Err(create_error!(NotFound))
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete attachment hash by id.
|
||||
async fn delete_attachment_hash(&self, id: &str) -> Result<()> {
|
||||
let mut file_hashes = self.file_hashes.lock().await;
|
||||
if file_hashes.remove(id).is_some() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(create_error!(NotFound))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,15 @@ pub trait AbstractAttachments: Sync + Send {
|
||||
/// Fetch an attachment by its id.
|
||||
async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result<File>;
|
||||
|
||||
/// Fetch all deleted attachments.
|
||||
async fn fetch_deleted_attachments(&self) -> Result<Vec<File>>;
|
||||
|
||||
/// Fetch all dangling attachments.
|
||||
async fn fetch_dangling_files(&self) -> Result<Vec<File>>;
|
||||
|
||||
/// Count references to a given hash.
|
||||
async fn count_file_hash_references(&self, hash: &str) -> Result<usize>;
|
||||
|
||||
/// Find an attachment by its details and mark it as used by a given parent.
|
||||
async fn find_and_use_attachment(
|
||||
&self,
|
||||
@@ -32,4 +41,7 @@ pub trait AbstractAttachments: Sync + Send {
|
||||
|
||||
/// Mark multiple attachments as having been deleted.
|
||||
async fn mark_attachments_as_deleted(&self, ids: &[String]) -> Result<()>;
|
||||
|
||||
/// Delete the attachment entry.
|
||||
async fn delete_attachment(&self, id: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,51 @@ impl AbstractAttachments for MongoDb {
|
||||
.ok_or_else(|| create_error!(NotFound))
|
||||
}
|
||||
|
||||
/// Fetch all deleted attachments.
|
||||
async fn fetch_deleted_attachments(&self) -> Result<Vec<File>> {
|
||||
query!(
|
||||
self,
|
||||
find,
|
||||
COL,
|
||||
doc! {
|
||||
"deleted": true,
|
||||
"reported": {
|
||||
"$ne": true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Fetch all dangling attachments.
|
||||
async fn fetch_dangling_files(&self) -> Result<Vec<File>> {
|
||||
query!(
|
||||
self,
|
||||
find,
|
||||
COL,
|
||||
doc! {
|
||||
"used_for.type": {
|
||||
"$exists": 0
|
||||
},
|
||||
"deleted": {
|
||||
"$ne": true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Count references to a given hash.
|
||||
async fn count_file_hash_references(&self, hash: &str) -> Result<usize> {
|
||||
query!(
|
||||
self,
|
||||
count_documents,
|
||||
COL,
|
||||
doc! {
|
||||
"hash": hash
|
||||
}
|
||||
)
|
||||
.map(|count| count as usize)
|
||||
}
|
||||
|
||||
/// Find an attachment by its details and mark it as used by a given parent.
|
||||
async fn find_and_use_attachment(
|
||||
&self,
|
||||
@@ -114,7 +159,7 @@ impl AbstractAttachments for MongoDb {
|
||||
/// Mark multiple attachments as having been deleted.
|
||||
async fn mark_attachments_as_deleted(&self, ids: &[String]) -> Result<()> {
|
||||
self.col::<Document>(COL)
|
||||
.update_one(
|
||||
.update_many(
|
||||
doc! {
|
||||
"_id": {
|
||||
"$in": ids
|
||||
@@ -129,7 +174,12 @@ impl AbstractAttachments for MongoDb {
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.map_err(|_| create_database_error!("update_one", COL))
|
||||
.map_err(|_| create_database_error!("update_many", COL))
|
||||
}
|
||||
|
||||
/// Delete the attachment entry.
|
||||
async fn delete_attachment(&self, id: &str) -> Result<()> {
|
||||
query!(self, delete_one_by_id, COL, id).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,41 @@ impl AbstractAttachments for ReferenceDb {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch all deleted attachments.
|
||||
async fn fetch_deleted_attachments(&self) -> Result<Vec<File>> {
|
||||
let files = self.files.lock().await;
|
||||
Ok(files
|
||||
.values()
|
||||
.filter(|file| {
|
||||
// file has been marked as deleted
|
||||
file.deleted.is_some_and(|v| v)
|
||||
// and it has not been reported
|
||||
&& !file.reported.is_some_and(|v| v)
|
||||
})
|
||||
.cloned()
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Fetch all dangling attachments.
|
||||
async fn fetch_dangling_files(&self) -> Result<Vec<File>> {
|
||||
let files = self.files.lock().await;
|
||||
Ok(files
|
||||
.values()
|
||||
.filter(|file| file.used_for.is_none() && !file.deleted.is_some_and(|v| v))
|
||||
.cloned()
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Count references to a given hash.
|
||||
async fn count_file_hash_references(&self, hash: &str) -> Result<usize> {
|
||||
let files = self.files.lock().await;
|
||||
Ok(files
|
||||
.values()
|
||||
.filter(|file| file.hash.as_ref().is_some_and(|h| h == hash))
|
||||
.cloned()
|
||||
.count())
|
||||
}
|
||||
|
||||
/// Find an attachment by its details and mark it as used by a given parent.
|
||||
async fn find_and_use_attachment(
|
||||
&self,
|
||||
@@ -96,4 +131,14 @@ impl AbstractAttachments for ReferenceDb {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete the attachment entry.
|
||||
async fn delete_attachment(&self, id: &str) -> Result<()> {
|
||||
let mut files = self.files.lock().await;
|
||||
if files.remove(id).is_some() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(create_error!(NotFound))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user