2022-05-07 20:27:11 +00:00
|
|
|
use chrono::{DateTime, Utc};
|
2021-04-09 00:22:17 +00:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
2023-01-17 23:14:18 +00:00
|
|
|
use crate::database::{DatabaseClient, DatabaseError};
|
2022-05-07 20:27:11 +00:00
|
|
|
use crate::models::cleanup::{
|
|
|
|
find_orphaned_files,
|
|
|
|
find_orphaned_ipfs_objects,
|
|
|
|
DeletionQueue,
|
|
|
|
};
|
2021-12-01 23:26:59 +00:00
|
|
|
use crate::utils::id::new_uuid;
|
2021-04-09 00:22:17 +00:00
|
|
|
use super::types::DbMediaAttachment;
|
|
|
|
|
|
|
|
pub async fn create_attachment(
|
2023-01-17 23:14:18 +00:00
|
|
|
db_client: &impl DatabaseClient,
|
2021-04-09 00:22:17 +00:00
|
|
|
owner_id: &Uuid,
|
|
|
|
file_name: String,
|
2023-01-19 21:57:29 +00:00
|
|
|
file_size: usize,
|
2021-12-29 13:57:57 +00:00
|
|
|
media_type: Option<String>,
|
2021-04-09 00:22:17 +00:00
|
|
|
) -> Result<DbMediaAttachment, DatabaseError> {
|
2021-12-01 23:26:59 +00:00
|
|
|
let attachment_id = new_uuid();
|
2023-01-19 21:57:29 +00:00
|
|
|
let file_size: i32 = file_size.try_into()
|
|
|
|
.expect("value should be within bounds");
|
2021-04-09 00:22:17 +00:00
|
|
|
let inserted_row = db_client.query_one(
|
|
|
|
"
|
2023-01-19 21:57:29 +00:00
|
|
|
INSERT INTO media_attachment (
|
|
|
|
id,
|
|
|
|
owner_id,
|
|
|
|
file_name,
|
|
|
|
file_size,
|
|
|
|
media_type
|
|
|
|
)
|
|
|
|
VALUES ($1, $2, $3, $4, $5)
|
2021-04-09 00:22:17 +00:00
|
|
|
RETURNING media_attachment
|
|
|
|
",
|
2023-01-19 21:57:29 +00:00
|
|
|
&[
|
|
|
|
&attachment_id,
|
|
|
|
&owner_id,
|
|
|
|
&file_name,
|
|
|
|
&file_size,
|
|
|
|
&media_type,
|
|
|
|
],
|
2021-04-09 00:22:17 +00:00
|
|
|
).await?;
|
|
|
|
let db_attachment: DbMediaAttachment = inserted_row.try_get("media_attachment")?;
|
|
|
|
Ok(db_attachment)
|
|
|
|
}
|
2021-09-25 20:46:19 +00:00
|
|
|
|
2021-09-28 21:44:31 +00:00
|
|
|
pub async fn set_attachment_ipfs_cid(
|
2023-01-17 23:14:18 +00:00
|
|
|
db_client: &impl DatabaseClient,
|
2021-09-28 21:44:31 +00:00
|
|
|
attachment_id: &Uuid,
|
|
|
|
ipfs_cid: &str,
|
|
|
|
) -> Result<DbMediaAttachment, DatabaseError> {
|
|
|
|
let maybe_row = db_client.query_opt(
|
|
|
|
"
|
|
|
|
UPDATE media_attachment
|
|
|
|
SET ipfs_cid = $1
|
2022-05-10 18:27:26 +00:00
|
|
|
WHERE id = $2 AND ipfs_cid IS NULL
|
2021-09-28 21:44:31 +00:00
|
|
|
RETURNING media_attachment
|
|
|
|
",
|
|
|
|
&[&ipfs_cid, &attachment_id],
|
|
|
|
).await?;
|
|
|
|
let row = maybe_row.ok_or(DatabaseError::NotFound("attachment"))?;
|
|
|
|
let db_attachment = row.try_get("media_attachment")?;
|
|
|
|
Ok(db_attachment)
|
|
|
|
}
|
2022-05-07 20:27:11 +00:00
|
|
|
|
|
|
|
pub async fn delete_unused_attachments(
|
2023-01-17 23:14:18 +00:00
|
|
|
db_client: &impl DatabaseClient,
|
2022-05-07 20:27:11 +00:00
|
|
|
created_before: &DateTime<Utc>,
|
|
|
|
) -> Result<DeletionQueue, DatabaseError> {
|
|
|
|
let rows = db_client.query(
|
|
|
|
"
|
|
|
|
DELETE FROM media_attachment
|
|
|
|
WHERE post_id IS NULL AND created_at < $1
|
|
|
|
RETURNING file_name, ipfs_cid
|
|
|
|
",
|
|
|
|
&[&created_before],
|
|
|
|
).await?;
|
|
|
|
let mut files = vec![];
|
|
|
|
let mut ipfs_objects = vec![];
|
|
|
|
for row in rows {
|
|
|
|
let file_name = row.try_get("file_name")?;
|
|
|
|
files.push(file_name);
|
|
|
|
if let Some(ipfs_cid) = row.try_get("ipfs_cid")? {
|
|
|
|
ipfs_objects.push(ipfs_cid);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let orphaned_files = find_orphaned_files(db_client, files).await?;
|
|
|
|
let orphaned_ipfs_objects = find_orphaned_ipfs_objects(db_client, ipfs_objects).await?;
|
|
|
|
Ok(DeletionQueue {
|
|
|
|
files: orphaned_files,
|
|
|
|
ipfs_objects: orphaned_ipfs_objects,
|
|
|
|
})
|
|
|
|
}
|