From ebf48e20bef13c2a2e9d1cc9de6343e5db4d8bd4 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 16 Mar 2023 12:21:28 -0400 Subject: [PATCH] list comments endpoint --- .../2023-03-16-003630_comments/up.sql | 2 + .../queries/comments/comment_entity_token.rs | 25 ++++ .../src/queries/comments/insert_comment.rs | 20 +-- .../comments/list_comments_for_entity.rs | 134 ++++++++++++++++++ .../src/queries/comments/mod.rs | 4 +- 5 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 crates/lib/database_queries/src/queries/comments/comment_entity_token.rs create mode 100644 crates/lib/database_queries/src/queries/comments/list_comments_for_entity.rs diff --git a/_sql/migrations/2023-03-16-003630_comments/up.sql b/_sql/migrations/2023-03-16-003630_comments/up.sql index 4488f7ee95..8a8dbbeb17 100644 --- a/_sql/migrations/2023-03-16-003630_comments/up.sql +++ b/_sql/migrations/2023-03-16-003630_comments/up.sql @@ -44,6 +44,8 @@ CREATE TABLE comments ( created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + -- Technically, this conveys *user* edits, not things that update the record itself. edited_at TIMESTAMP NULL, -- If this is removed by a mod. diff --git a/crates/lib/database_queries/src/queries/comments/comment_entity_token.rs b/crates/lib/database_queries/src/queries/comments/comment_entity_token.rs new file mode 100644 index 0000000000..122503f766 --- /dev/null +++ b/crates/lib/database_queries/src/queries/comments/comment_entity_token.rs @@ -0,0 +1,25 @@ +use enums::by_table::comments::comment_entity_type::CommentEntityType; +use tokens::tokens::tts_models::TtsModelToken; +use tokens::tokens::w2l_templates::W2lTemplateToken; +use tokens::users::user::UserToken; + +pub enum CommentEntityToken { + User(UserToken), + TtsModel(TtsModelToken), + TtsResult(String), // TODO: Strong type + W2lTemplate(W2lTemplateToken), + W2lResult(String), // TODO: Strong type +} + +impl CommentEntityToken { + pub fn get_composite_keys(&self) -> (CommentEntityType, &str) { + let (entity_type, entity_token) = match self { + CommentEntityToken::User(user_token) => (CommentEntityType::User, user_token.as_str()), + CommentEntityToken::TtsModel(tts_model_token) => (CommentEntityType::TtsModel, tts_model_token.as_str()), + CommentEntityToken::TtsResult(tts_result_token) => (CommentEntityType::TtsResult, tts_result_token.as_str()), + CommentEntityToken::W2lTemplate(w2l_template_token) => (CommentEntityType::W2lTemplate, w2l_template_token.as_str()), + CommentEntityToken::W2lResult(w2l_result_token) => (CommentEntityType::W2lResult, w2l_result_token.as_str()), + }; + (entity_type, entity_token) + } +} diff --git a/crates/lib/database_queries/src/queries/comments/insert_comment.rs b/crates/lib/database_queries/src/queries/comments/insert_comment.rs index 420dabc67e..842ee425f0 100644 --- a/crates/lib/database_queries/src/queries/comments/insert_comment.rs +++ b/crates/lib/database_queries/src/queries/comments/insert_comment.rs @@ -1,24 +1,17 @@ use anyhow::anyhow; use chrono::Utc; +use crate::queries::comments::comment_entity_token::CommentEntityToken; +use enums::by_table::comments::comment_entity_type::CommentEntityType; use enums::common::visibility::Visibility; use errors::AnyhowResult; use sqlx::MySqlPool; use std::path::Path; -use enums::by_table::comments::comment_entity_type::CommentEntityType; use tokens::tokens::comments::CommentToken; use tokens::tokens::tts_models::TtsModelToken; use tokens::tokens::w2l_templates::W2lTemplateToken; use tokens::users::user::UserToken; use tokens::voice_conversion::model::VoiceConversionModelToken; -pub enum CommentEntityToken { - User(UserToken), - TtsModel(TtsModelToken), - TtsResult(String), // TODO: Strong type - W2lTemplate(W2lTemplateToken), - W2lResult(String), // TODO: Strong type -} - pub struct Args<'a> { pub entity_token: &'a CommentEntityToken, @@ -40,14 +33,7 @@ pub async fn insert_comment( ) -> AnyhowResult { let comment_token = CommentToken::generate(); - - let (entity_type, entity_token) = match args.entity_token { - CommentEntityToken::User(user_token) => (CommentEntityType::User, user_token.as_str()), - CommentEntityToken::TtsModel(tts_model_token) => (CommentEntityType::TtsModel, tts_model_token.as_str()), - CommentEntityToken::TtsResult(tts_result_token) => (CommentEntityType::TtsResult, tts_result_token.as_str()), - CommentEntityToken::W2lTemplate(w2l_template_token) => (CommentEntityType::W2lTemplate, w2l_template_token.as_str()), - CommentEntityToken::W2lResult(w2l_result_token) => (CommentEntityType::W2lResult, w2l_result_token.as_str()), - }; + let (entity_type, entity_token) = args.entity_token.get_composite_keys(); let query_result = sqlx::query!( r#" diff --git a/crates/lib/database_queries/src/queries/comments/list_comments_for_entity.rs b/crates/lib/database_queries/src/queries/comments/list_comments_for_entity.rs new file mode 100644 index 0000000000..5dba532b54 --- /dev/null +++ b/crates/lib/database_queries/src/queries/comments/list_comments_for_entity.rs @@ -0,0 +1,134 @@ +use anyhow::anyhow; +use chrono::{DateTime, Utc}; +use crate::queries::comments::comment_entity_token::CommentEntityToken; +use enums::by_table::comments::comment_entity_type::CommentEntityType; +use errors::AnyhowResult; +use log::warn; +use sqlx::MySqlPool; +use tokens::tokens::comments::CommentToken; +use tokens::users::user::UserToken; + +pub struct CommentForList { + pub token: CommentToken, + + pub user_token: UserToken, + pub username: String, + pub user_display_name: String, + + pub comment_markdown: String, + pub comment_rendered_html: String, + + pub mod_fields: CommentForListModFields, + + pub created_at: DateTime, + pub updated_at: DateTime, + pub maybe_edited_at: Option>, +} + +pub struct CommentForListModFields { + pub creator_ip_address: String, + pub editor_ip_address: String, + pub maybe_user_deleted_at: Option>, + pub maybe_mod_deleted_at: Option>, + pub maybe_object_owner_deleted_at: Option>, +} + +pub async fn list_comments_for_entity( + comment_entity_token: CommentEntityToken, + mysql_pool: &MySqlPool +) -> AnyhowResult> { + + let (entity_type, entity_token) = comment_entity_token.get_composite_keys(); + + let maybe_results= sqlx::query_as!( + RawCommentForList, + r#" +SELECT + c.token as `token: tokens::tokens::comments::CommentToken`, + c.user_token as `user_token: tokens::users::user::UserToken`, + u.username, + u.display_name as user_display_name, + + c.comment_markdown, + c.comment_rendered_html, + + c.creator_ip_address, + c.editor_ip_address, + + c.created_at, + c.updated_at, + c.edited_at, + c.user_deleted_at, + c.mod_deleted_at, + c.object_owner_deleted_at + +FROM + comments AS c +JOIN users AS u + ON c.user_token = u.token +WHERE + c.entity_type = ? + AND c.entity_token = ? + AND c.user_deleted_at IS NULL + AND c.mod_deleted_at IS NULL + AND c.object_owner_deleted_at IS NULL +ORDER BY c.id DESC +LIMIT 50 + "#, + entity_type, + entity_token + ) + .fetch_all(mysql_pool) + .await; + + match maybe_results { + Err(err) => match err { + sqlx::Error::RowNotFound => Ok(Vec::new()), + _ => { + warn!("list ip bans db error: {:?}", err); + Err(anyhow!("error with query: {:?}", err)) + } + }, + Ok(results) => Ok(results.into_iter() + .map(|comment| CommentForList { + token: comment.token, + user_token: comment.user_token, + username: comment.username, + user_display_name: comment.user_display_name, + comment_markdown: comment.comment_markdown, + comment_rendered_html: comment.comment_rendered_html, + mod_fields: CommentForListModFields { + creator_ip_address: comment.creator_ip_address, + editor_ip_address: comment.editor_ip_address, + maybe_user_deleted_at: comment.user_deleted_at, + maybe_mod_deleted_at: comment.mod_deleted_at, + maybe_object_owner_deleted_at: comment.object_owner_deleted_at, + }, + created_at: comment.created_at, + updated_at: comment.updated_at, + maybe_edited_at: None, + }) + .collect()), + } +} + +pub struct RawCommentForList { + pub token: CommentToken, + + pub user_token: UserToken, + pub username: String, + pub user_display_name: String, + + pub comment_markdown: String, + pub comment_rendered_html: String, + + pub creator_ip_address: String, + pub editor_ip_address: String, + + pub created_at: DateTime, + pub updated_at: DateTime, + pub edited_at: Option>, + pub user_deleted_at: Option>, + pub mod_deleted_at: Option>, + pub object_owner_deleted_at: Option>, +} diff --git a/crates/lib/database_queries/src/queries/comments/mod.rs b/crates/lib/database_queries/src/queries/comments/mod.rs index 3fc7c6dab6..27cd4afb49 100644 --- a/crates/lib/database_queries/src/queries/comments/mod.rs +++ b/crates/lib/database_queries/src/queries/comments/mod.rs @@ -1 +1,3 @@ -pub mod insert_comment; \ No newline at end of file +pub mod comment_entity_token; +pub mod insert_comment; +pub mod list_comments_for_entity; \ No newline at end of file