Delete media attached to descendants of post when it is deleted

This commit is contained in:
silverpill 2022-02-19 23:14:42 +00:00
parent 9bc8997fb5
commit 54277e410d

View file

@ -468,12 +468,12 @@ pub async fn get_thread(
SELECT post.id, post.in_reply_to_id FROM post SELECT post.id, post.in_reply_to_id FROM post
JOIN ancestors ON post.id = ancestors.in_reply_to_id JOIN ancestors ON post.id = ancestors.in_reply_to_id
), ),
context (id, path) AS ( thread (id, path) AS (
SELECT ancestors.id, ARRAY[ancestors.id] FROM ancestors SELECT ancestors.id, ARRAY[ancestors.id] FROM ancestors
WHERE ancestors.in_reply_to_id IS NULL WHERE ancestors.in_reply_to_id IS NULL
UNION UNION
SELECT post.id, array_append(context.path, post.id) FROM post SELECT post.id, array_append(thread.path, post.id) FROM post
JOIN context ON post.in_reply_to_id = context.id JOIN thread ON post.in_reply_to_id = thread.id
) )
SELECT SELECT
post, actor_profile, post, actor_profile,
@ -481,10 +481,10 @@ pub async fn get_thread(
{related_mentions}, {related_mentions},
{related_tags} {related_tags}
FROM post FROM post
JOIN context ON post.id = context.id JOIN thread ON post.id = thread.id
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE {visibility_filter} WHERE {visibility_filter}
ORDER BY context.path ORDER BY thread.path
", ",
related_attachments=RELATED_ATTACHMENTS, related_attachments=RELATED_ATTACHMENTS,
related_mentions=RELATED_MENTIONS, related_mentions=RELATED_MENTIONS,
@ -733,13 +733,34 @@ pub async fn delete_post(
post_id: &Uuid, post_id: &Uuid,
) -> Result<DeletionQueue, DatabaseError> { ) -> Result<DeletionQueue, DatabaseError> {
let transaction = db_client.transaction().await?; let transaction = db_client.transaction().await?;
// Select all posts that will be deleted.
// This includes given post, its descendants and reposts.
let posts_rows = transaction.query(
"
WITH RECURSIVE context (post_id) AS (
SELECT post.id FROM post
WHERE post.id = $1
UNION
SELECT post.id FROM post
JOIN context ON (
post.in_reply_to_id = context.post_id
OR post.repost_of_id = context.post_id
)
)
SELECT post_id FROM context
",
&[&post_id],
).await?;
let posts: Vec<Uuid> = posts_rows.iter()
.map(|row| row.try_get("post_id"))
.collect::<Result<_, _>>()?;
// Get list of attached files // Get list of attached files
let files_rows = transaction.query( let files_rows = transaction.query(
" "
SELECT file_name SELECT file_name
FROM media_attachment WHERE post_id = $1 FROM media_attachment WHERE post_id = ANY($1)
", ",
&[&post_id], &[&posts],
).await?; ).await?;
let files: Vec<String> = files_rows.iter() let files: Vec<String> = files_rows.iter()
.map(|row| row.try_get("file_name")) .map(|row| row.try_get("file_name"))
@ -749,17 +770,31 @@ pub async fn delete_post(
" "
SELECT ipfs_cid SELECT ipfs_cid
FROM media_attachment FROM media_attachment
WHERE post_id = $1 AND ipfs_cid IS NOT NULL WHERE post_id = ANY($1) AND ipfs_cid IS NOT NULL
UNION ALL UNION ALL
SELECT ipfs_cid SELECT ipfs_cid
FROM post FROM post
WHERE id = $1 AND ipfs_cid IS NOT NULL WHERE id = ANY($1) AND ipfs_cid IS NOT NULL
", ",
&[&post_id], &[&posts],
).await?; ).await?;
let ipfs_objects: Vec<String> = ipfs_objects_rows.iter() let ipfs_objects: Vec<String> = ipfs_objects_rows.iter()
.map(|row| row.try_get("ipfs_cid")) .map(|row| row.try_get("ipfs_cid"))
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
// Update post counters
transaction.execute(
"
UPDATE actor_profile
SET post_count = post_count - post.count
FROM (
SELECT post.author_id, count(*) FROM post
WHERE post.id = ANY($1)
GROUP BY post.author_id
) AS post
WHERE actor_profile.id = post.author_id
",
&[&posts],
).await?;
// Delete post // Delete post
let maybe_post_row = transaction.query_opt( let maybe_post_row = transaction.query_opt(
" "
@ -777,7 +812,6 @@ pub async fn delete_post(
if let Some(repost_of_id) = &db_post.repost_of_id { if let Some(repost_of_id) = &db_post.repost_of_id {
update_repost_count(&transaction, repost_of_id, -1).await?; update_repost_count(&transaction, repost_of_id, -1).await?;
}; };
update_post_count(&transaction, &db_post.author_id, -1).await?;
let orphaned_files = find_orphaned_files(&transaction, files).await?; let orphaned_files = find_orphaned_files(&transaction, files).await?;
let orphaned_ipfs_objects = find_orphaned_ipfs_objects(&transaction, ipfs_objects).await?; let orphaned_ipfs_objects = find_orphaned_ipfs_objects(&transaction, ipfs_objects).await?;
transaction.commit().await?; transaction.commit().await?;