This commit is contained in:
parent
cfef57d8a1
commit
e1dd679c47
19 changed files with 1807 additions and 73 deletions
193
src/db.rs
193
src/db.rs
|
|
@ -9,12 +9,12 @@ use uuid::Uuid;
|
|||
|
||||
use crate::{
|
||||
entity::{
|
||||
channels, direct_messages, guild_members, guilds, invites, messages, soundboard_sounds,
|
||||
users,
|
||||
attachments, channels, direct_messages, guild_members, guilds, invites, messages,
|
||||
soundboard_sounds, users,
|
||||
},
|
||||
models::{
|
||||
BasicUser, Channel, DmConversation, DmMessageWithAuthor, Guild, Invite, MessageWithAuthor,
|
||||
SoundboardSound, User,
|
||||
Attachment, BasicUser, Channel, DmConversation, DmMessageWithAuthor, Guild, Invite,
|
||||
MessageWithAuthor, SoundboardSound, User,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -350,6 +350,63 @@ pub async fn create_message(
|
|||
author_user_id: model.author_user_id,
|
||||
author_display_name: user.display_name,
|
||||
body: model.body,
|
||||
attachments: Vec::new(),
|
||||
created_at: model.created_at,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn create_message_with_attachment(
|
||||
db: &DatabaseConnection,
|
||||
channel_id: Uuid,
|
||||
author_user_id: Uuid,
|
||||
body: &str,
|
||||
object_key: &str,
|
||||
media_url: &str,
|
||||
mime_type: &str,
|
||||
size_bytes: i64,
|
||||
original_filename: &str,
|
||||
) -> Result<MessageWithAuthor> {
|
||||
let txn = db.begin().await?;
|
||||
|
||||
let model = messages::Entity::insert(messages::ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
channel_id: Set(channel_id),
|
||||
author_user_id: Set(author_user_id),
|
||||
body: Set(body.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.exec_with_returning(&txn)
|
||||
.await?;
|
||||
|
||||
let attachment = attachments::Entity::insert(attachments::ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
channel_message_id: Set(Some(model.id)),
|
||||
direct_message_id: Set(None),
|
||||
uploader_user_id: Set(author_user_id),
|
||||
object_key: Set(object_key.to_string()),
|
||||
media_url: Set(media_url.to_string()),
|
||||
mime_type: Set(mime_type.to_string()),
|
||||
size_bytes: Set(size_bytes),
|
||||
original_filename: Set(original_filename.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.exec_with_returning(&txn)
|
||||
.await?;
|
||||
|
||||
let user = users::Entity::find_by_id(author_user_id)
|
||||
.one(&txn)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("author not found"))?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
Ok(MessageWithAuthor {
|
||||
id: model.id,
|
||||
channel_id: model.channel_id,
|
||||
author_user_id: model.author_user_id,
|
||||
author_display_name: user.display_name,
|
||||
body: model.body,
|
||||
attachments: vec![map_attachment(attachment)],
|
||||
created_at: model.created_at,
|
||||
})
|
||||
}
|
||||
|
|
@ -367,6 +424,10 @@ pub async fn list_messages(
|
|||
.all(db)
|
||||
.await?;
|
||||
|
||||
let attachment_map =
|
||||
list_attachments_for_channel_messages(db, rows.iter().map(|(msg, _)| msg.id).collect())
|
||||
.await?;
|
||||
|
||||
Ok(rows
|
||||
.into_iter()
|
||||
.map(|(msg, user)| {
|
||||
|
|
@ -379,6 +440,7 @@ pub async fn list_messages(
|
|||
author_user_id: msg.author_user_id,
|
||||
author_display_name,
|
||||
body: msg.body,
|
||||
attachments: attachment_map.get(&msg.id).cloned().unwrap_or_default(),
|
||||
created_at: msg.created_at,
|
||||
}
|
||||
})
|
||||
|
|
@ -412,6 +474,63 @@ pub async fn create_direct_message(
|
|||
recipient_user_id: model.recipient_user_id,
|
||||
author_display_name: user.display_name,
|
||||
body: model.body,
|
||||
attachments: Vec::new(),
|
||||
created_at: model.created_at,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn create_direct_message_with_attachment(
|
||||
db: &DatabaseConnection,
|
||||
sender_user_id: Uuid,
|
||||
recipient_user_id: Uuid,
|
||||
body: &str,
|
||||
object_key: &str,
|
||||
media_url: &str,
|
||||
mime_type: &str,
|
||||
size_bytes: i64,
|
||||
original_filename: &str,
|
||||
) -> Result<DmMessageWithAuthor> {
|
||||
let txn = db.begin().await?;
|
||||
|
||||
let model = direct_messages::Entity::insert(direct_messages::ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
sender_user_id: Set(sender_user_id),
|
||||
recipient_user_id: Set(recipient_user_id),
|
||||
body: Set(body.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.exec_with_returning(&txn)
|
||||
.await?;
|
||||
|
||||
let attachment = attachments::Entity::insert(attachments::ActiveModel {
|
||||
id: Set(Uuid::new_v4()),
|
||||
channel_message_id: Set(None),
|
||||
direct_message_id: Set(Some(model.id)),
|
||||
uploader_user_id: Set(sender_user_id),
|
||||
object_key: Set(object_key.to_string()),
|
||||
media_url: Set(media_url.to_string()),
|
||||
mime_type: Set(mime_type.to_string()),
|
||||
size_bytes: Set(size_bytes),
|
||||
original_filename: Set(original_filename.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.exec_with_returning(&txn)
|
||||
.await?;
|
||||
|
||||
let user = users::Entity::find_by_id(sender_user_id)
|
||||
.one(&txn)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("sender not found"))?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
Ok(DmMessageWithAuthor {
|
||||
id: model.id,
|
||||
author_user_id: model.sender_user_id,
|
||||
recipient_user_id: model.recipient_user_id,
|
||||
author_display_name: user.display_name,
|
||||
body: model.body,
|
||||
attachments: vec![map_attachment(attachment)],
|
||||
created_at: model.created_at,
|
||||
})
|
||||
}
|
||||
|
|
@ -454,6 +573,9 @@ pub async fn list_direct_messages(
|
|||
.map(|u| (u.id, u.display_name))
|
||||
.collect();
|
||||
|
||||
let attachment_map =
|
||||
list_attachments_for_direct_messages(db, rows.iter().map(|msg| msg.id).collect()).await?;
|
||||
|
||||
Ok(rows
|
||||
.into_iter()
|
||||
.map(|msg| DmMessageWithAuthor {
|
||||
|
|
@ -465,11 +587,64 @@ pub async fn list_direct_messages(
|
|||
.cloned()
|
||||
.unwrap_or_else(|| "Unknown User".to_string()),
|
||||
body: msg.body,
|
||||
attachments: attachment_map.get(&msg.id).cloned().unwrap_or_default(),
|
||||
created_at: msg.created_at,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn list_attachments_for_channel_messages(
|
||||
db: &DatabaseConnection,
|
||||
message_ids: Vec<Uuid>,
|
||||
) -> Result<std::collections::HashMap<Uuid, Vec<Attachment>>> {
|
||||
if message_ids.is_empty() {
|
||||
return Ok(std::collections::HashMap::new());
|
||||
}
|
||||
|
||||
let rows = attachments::Entity::find()
|
||||
.filter(attachments::Column::ChannelMessageId.is_in(message_ids))
|
||||
.order_by_asc(attachments::Column::CreatedAt)
|
||||
.all(db)
|
||||
.await?;
|
||||
|
||||
let mut grouped = std::collections::HashMap::<Uuid, Vec<Attachment>>::new();
|
||||
for row in rows {
|
||||
if let Some(message_id) = row.channel_message_id {
|
||||
grouped
|
||||
.entry(message_id)
|
||||
.or_default()
|
||||
.push(map_attachment(row));
|
||||
}
|
||||
}
|
||||
Ok(grouped)
|
||||
}
|
||||
|
||||
async fn list_attachments_for_direct_messages(
|
||||
db: &DatabaseConnection,
|
||||
message_ids: Vec<Uuid>,
|
||||
) -> Result<std::collections::HashMap<Uuid, Vec<Attachment>>> {
|
||||
if message_ids.is_empty() {
|
||||
return Ok(std::collections::HashMap::new());
|
||||
}
|
||||
|
||||
let rows = attachments::Entity::find()
|
||||
.filter(attachments::Column::DirectMessageId.is_in(message_ids))
|
||||
.order_by_asc(attachments::Column::CreatedAt)
|
||||
.all(db)
|
||||
.await?;
|
||||
|
||||
let mut grouped = std::collections::HashMap::<Uuid, Vec<Attachment>>::new();
|
||||
for row in rows {
|
||||
if let Some(message_id) = row.direct_message_id {
|
||||
grouped
|
||||
.entry(message_id)
|
||||
.or_default()
|
||||
.push(map_attachment(row));
|
||||
}
|
||||
}
|
||||
Ok(grouped)
|
||||
}
|
||||
|
||||
pub async fn list_dm_conversations(
|
||||
db: &DatabaseConnection,
|
||||
current_user_id: Uuid,
|
||||
|
|
@ -543,6 +718,16 @@ fn map_guild(model: guilds::Model) -> Guild {
|
|||
}
|
||||
}
|
||||
|
||||
fn map_attachment(model: attachments::Model) -> Attachment {
|
||||
Attachment {
|
||||
id: model.id,
|
||||
media_url: model.media_url,
|
||||
mime_type: model.mime_type,
|
||||
size_bytes: model.size_bytes,
|
||||
original_filename: model.original_filename,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_channel(model: channels::Model) -> Channel {
|
||||
Channel {
|
||||
id: model.id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue