chore: update code to maybe final version

This commit is contained in:
phiresky 2024-12-13 13:59:28 +01:00
parent fcd7c6d0eb
commit 03b850ed75
10 changed files with 52 additions and 133 deletions

View file

@ -1,13 +1,7 @@
use crate::{
newtypes::{CommunityId, TagId},
schema::{community_post_tag, post_tag, tag},
source::community_post_tag::{
CommunityPostTag,
CommunityPostTagInsertForm,
PostTagInsertForm,
Tag,
TagInsertForm,
},
newtypes::TagId,
schema::{post_tag, tag},
source::tag::{PostTagInsertForm, Tag, TagInsertForm},
traits::Crud,
utils::{get_conn, DbPool},
};
@ -45,35 +39,6 @@ impl Crud for Tag {
}
}
#[async_trait]
impl Crud for CommunityPostTag {
type InsertForm = CommunityPostTagInsertForm;
type UpdateForm = CommunityPostTagInsertForm;
type IdType = (CommunityId, TagId);
async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
let conn = &mut get_conn(pool).await?;
insert_into(community_post_tag::table)
.values(form)
.get_result::<Self>(conn)
.await
}
async fn update(
pool: &mut DbPool<'_>,
pid: (CommunityId, TagId),
form: &Self::UpdateForm,
) -> Result<Self, Error> {
let conn = &mut get_conn(pool).await?;
diesel::update(community_post_tag::table.find(pid))
.set(form)
.get_result::<Self>(conn)
.await
}
}
impl PostTagInsertForm {
pub async fn insert_tag_associations(
pool: &mut DbPool<'_>,

View file

@ -263,14 +263,6 @@ diesel::table! {
}
}
diesel::table! {
community_post_tag (community_id, tag_id) {
community_id -> Int4,
tag_id -> Int4,
published -> Timestamptz,
}
}
diesel::table! {
custom_emoji (id) {
id -> Int4,
@ -972,9 +964,10 @@ diesel::table! {
id -> Int4,
ap_id -> Text,
name -> Text,
community_id -> Int4,
published -> Timestamptz,
updated -> Nullable<Timestamptz>,
deleted -> Nullable<Timestamptz>,
deleted -> Bool,
}
}
@ -1011,8 +1004,6 @@ diesel::joinable!(community_actions -> community (community_id));
diesel::joinable!(community_aggregates -> community (community_id));
diesel::joinable!(community_language -> community (community_id));
diesel::joinable!(community_language -> language (language_id));
diesel::joinable!(community_post_tag -> community (community_id));
diesel::joinable!(community_post_tag -> tag (tag_id));
diesel::joinable!(custom_emoji_keyword -> custom_emoji (custom_emoji_id));
diesel::joinable!(email_verification -> local_user (local_user_id));
diesel::joinable!(federation_allowlist -> instance (instance_id));
@ -1070,6 +1061,7 @@ diesel::joinable!(site -> instance (instance_id));
diesel::joinable!(site_aggregates -> site (site_id));
diesel::joinable!(site_language -> language (language_id));
diesel::joinable!(site_language -> site (site_id));
diesel::joinable!(tag -> community (community_id));
diesel::allow_tables_to_appear_in_same_query!(
admin_allow_instance,
@ -1088,7 +1080,6 @@ diesel::allow_tables_to_appear_in_same_query!(
community_actions,
community_aggregates,
community_language,
community_post_tag,
custom_emoji,
custom_emoji_keyword,
email_verification,

View file

@ -10,7 +10,6 @@ pub mod comment_reply;
pub mod comment_report;
pub mod community;
pub mod community_block;
pub mod community_post_tag;
pub mod custom_emoji;
pub mod custom_emoji_keyword;
pub mod email_verification;
@ -41,6 +40,7 @@ pub mod private_message_report;
pub mod registration_application;
pub mod secret;
pub mod site;
pub mod tag;
pub mod tagline;
/// Default value for columns like [community::Community.inbox_url] which are marked as serde(skip).

View file

@ -1,6 +1,6 @@
use crate::newtypes::{CommunityId, DbUrl, PostId, TagId};
#[cfg(feature = "full")]
use crate::schema::{community_post_tag, post_tag, tag};
use crate::schema::{post_tag, tag};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
@ -10,6 +10,13 @@ use ts_rs::TS;
/// A tag that can be assigned to a post within a community.
/// The tag object is created by the community moderators.
/// The assignment happens by the post creator and can be updated by the community moderators.
///
/// A tag is a federatable object that gives additional context to another object, which can be
/// displayed and filtered on currently, we only have community post tags, which is a tag that is
/// created by post authors as well as mods of a community, to categorize a post. in the future we
/// may add more tag types, depending on the requirements, this will lead to either expansion of
/// this table (community_id optional, addition of tag_type enum) or split of this table / creation
/// of new tables.
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "full", derive(TS, Queryable, Selectable, Identifiable))]
@ -20,22 +27,11 @@ pub struct Tag {
pub id: TagId,
pub ap_id: DbUrl,
pub name: String,
/// the community that owns this tag
pub community_id: CommunityId,
pub published: DateTime<Utc>,
pub updated: Option<DateTime<Utc>>,
pub deleted: Option<DateTime<Utc>>,
}
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "full", derive(TS, Queryable, Selectable, Identifiable))]
#[cfg_attr(feature = "full", diesel(table_name = community_post_tag))]
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
#[cfg_attr(feature = "full", diesel(primary_key(community_id, tag_id)))]
#[cfg_attr(feature = "full", ts(export))]
pub struct CommunityPostTag {
pub community_id: CommunityId,
pub tag_id: TagId,
pub published: DateTime<Utc>,
pub deleted: bool,
}
#[derive(Debug, Clone)]
@ -44,19 +40,11 @@ pub struct CommunityPostTag {
pub struct TagInsertForm {
pub ap_id: DbUrl,
pub name: String,
pub community_id: CommunityId,
// default now
pub published: Option<DateTime<Utc>>,
pub updated: Option<DateTime<Utc>>,
pub deleted: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
#[cfg_attr(feature = "full", diesel(table_name = community_post_tag))]
pub struct CommunityPostTagInsertForm {
pub community_id: CommunityId,
pub tag_id: TagId,
pub published: Option<DateTime<Utc>>,
pub deleted: bool,
}
#[derive(Debug, Clone)]

View file

@ -6,8 +6,6 @@ pub mod comment_report_view;
#[cfg(feature = "full")]
pub mod comment_view;
#[cfg(feature = "full")]
pub mod community_post_tags_view;
#[cfg(feature = "full")]
pub mod custom_emoji_view;
#[cfg(feature = "full")]
pub mod local_image_view;
@ -16,6 +14,8 @@ pub mod local_user_view;
#[cfg(feature = "full")]
pub mod post_report_view;
#[cfg(feature = "full")]
pub mod post_tags_view;
#[cfg(feature = "full")]
pub mod post_view;
#[cfg(feature = "full")]
pub mod private_message_report_view;

View file

@ -1,4 +1,5 @@
use crate::structs::PostCommunityPostTags;
//! see post_view.rs for the reason for this json decoding
use crate::structs::PostTags;
use diesel::{
deserialize::FromSql,
pg::{Pg, PgValue},
@ -6,10 +7,10 @@ use diesel::{
sql_types::{self, Nullable},
};
impl FromSql<Nullable<sql_types::Json>, Pg> for PostCommunityPostTags {
impl FromSql<Nullable<sql_types::Json>, Pg> for PostTags {
fn from_sql(bytes: PgValue) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<sql_types::Json, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value::<PostCommunityPostTags>(value)?)
Ok(serde_json::from_value::<PostTags>(value)?)
}
fn from_nullable_sql(
bytes: Option<<Pg as diesel::backend::Backend>::RawValue<'_>>,
@ -21,7 +22,7 @@ impl FromSql<Nullable<sql_types::Json>, Pg> for PostCommunityPostTags {
}
}
impl ToSql<Nullable<sql_types::Json>, Pg> for PostCommunityPostTags {
impl ToSql<Nullable<sql_types::Json>, Pg> for PostTags {
fn to_sql(&self, out: &mut diesel::serialize::Output<Pg>) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<sql_types::Json, Pg>>::to_sql(&value, &mut out.reborrow())

View file

@ -106,6 +106,7 @@ fn queries<'a>() -> Queries<
"json_agg(tag.*)",
))
.filter(post_tag::post_id.eq(post_aggregates::post_id))
.filter(tag::deleted.eq(false))
.single_value(),
);
query
@ -638,7 +639,7 @@ impl<'a> PostQuery<'a> {
mod tests {
use crate::{
post_view::{PaginationCursorData, PostQuery, PostView},
structs::{LocalUserView, PostCommunityPostTags},
structs::{LocalUserView, PostTags},
};
use chrono::Utc;
use diesel_async::SimpleAsyncConnection;
@ -662,13 +663,6 @@ mod tests {
CommunityUpdateForm,
},
community_block::{CommunityBlock, CommunityBlockForm},
community_post_tag::{
CommunityPostTag,
CommunityPostTagInsertForm,
PostTagInsertForm,
Tag,
TagInsertForm,
},
instance::Instance,
instance_block::{InstanceBlock, InstanceBlockForm},
language::Language,
@ -689,6 +683,7 @@ mod tests {
PostUpdateForm,
},
site::Site,
tag::{PostTagInsertForm, Tag, TagInsertForm},
},
traits::{Bannable, Blockable, Crud, Followable, Joinable, Likeable, Saveable},
utils::{build_db_pool, get_conn, uplete, ActualDbPool, DbPool, RANK_DEFAULT},
@ -809,18 +804,10 @@ mod tests {
&TagInsertForm {
ap_id: Url::parse(&format!("{}/tags/test_tag1", inserted_community.actor_id))?.into(),
name: "Test Tag 1".into(),
community_id: inserted_community.id,
published: None,
updated: None,
deleted: None,
},
)
.await?;
CommunityPostTag::create(
pool,
&CommunityPostTagInsertForm {
community_id: inserted_community.id,
tag_id: tag_1.id,
published: None,
deleted: false,
},
)
.await?;
@ -829,18 +816,10 @@ mod tests {
&TagInsertForm {
ap_id: Url::parse(&format!("{}/tags/test_tag2", inserted_community.actor_id))?.into(),
name: "Test Tag 2".into(),
community_id: inserted_community.id,
published: None,
updated: None,
deleted: None,
},
)
.await?;
CommunityPostTag::create(
pool,
&CommunityPostTagInsertForm {
community_id: inserted_community.id,
tag_id: tag_2.id,
published: None,
deleted: false,
},
)
.await?;
@ -1921,7 +1900,7 @@ mod tests {
hidden: false,
saved: false,
creator_blocked: false,
community_post_tags: PostCommunityPostTags::default(),
tags: PostTags::default(),
})
}
@ -2236,14 +2215,14 @@ mod tests {
)
.await?;
assert_eq!(2, post_view.community_post_tags.tags.len());
assert_eq!(data.tag_1.name, post_view.community_post_tags.tags[0].name);
assert_eq!(data.tag_2.name, post_view.community_post_tags.tags[1].name);
assert_eq!(2, post_view.tags.tags.len());
assert_eq!(data.tag_1.name, post_view.tags.tags[0].name);
assert_eq!(data.tag_2.name, post_view.tags.tags[1].name);
let all_posts = data.default_post_query().list(&data.site, pool).await?;
assert_eq!(2, all_posts[0].community_post_tags.tags.len()); // post with tags
assert_eq!(0, all_posts[1].community_post_tags.tags.len()); // bot post
assert_eq!(0, all_posts[2].community_post_tags.tags.len()); // normal post
assert_eq!(2, all_posts[0].tags.tags.len()); // post with tags
assert_eq!(0, all_posts[1].tags.tags.len()); // bot post
assert_eq!(0, all_posts[2].tags.tags.len()); // normal post
Ok(())
}

View file

@ -8,7 +8,6 @@ use lemmy_db_schema::{
comment::Comment,
comment_report::CommentReport,
community::Community,
community_post_tag::Tag,
custom_emoji::CustomEmoji,
custom_emoji_keyword::CustomEmojiKeyword,
images::{ImageDetails, LocalImage},
@ -23,6 +22,7 @@ use lemmy_db_schema::{
private_message_report::PrivateMessageReport,
registration_application::RegistrationApplication,
site::Site,
tag::Tag,
},
SubscribedType,
};
@ -154,7 +154,7 @@ pub struct PostView {
#[cfg_attr(feature = "full", ts(optional))]
pub my_vote: Option<i16>,
pub unread_comments: i64,
pub community_post_tags: PostCommunityPostTags,
pub tags: PostTags,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
@ -246,6 +246,7 @@ pub struct LocalImageView {
#[cfg_attr(feature = "full", derive(TS, FromSqlRow, AsExpression))]
#[serde(transparent)]
#[cfg_attr(feature = "full", diesel(sql_type = Nullable<sql_types::Json>))]
pub struct PostCommunityPostTags {
/// we wrap this in a struct so we can implement FromSqlRow<Json> for it
pub struct PostTags {
pub tags: Vec<Tag>,
}

View file

@ -1,7 +1,4 @@
-- This file should undo anything in `up.sql`
DROP TABLE post_tag;
DROP TABLE community_post_tag;
DROP TABLE tag;

View file

@ -1,19 +1,16 @@
-- a tag for a post, valid in a community. created by mods of a community
-- a tag is a federatable object that gives additional context to another object, which can be displayed and filtered on
-- currently, we only have community post tags, which is a tag that is created by post authors as well as mods of a community,
-- to categorize a post. in the future we may add more tag types, depending on the requirements,
-- this will lead to either expansion of this table (community_id optional, addition of tag_type enum)
-- or split of this table / creation of new tables.
CREATE TABLE tag (
id serial PRIMARY KEY,
ap_id text NOT NULL UNIQUE,
name text NOT NULL,
community_id int NOT NULL REFERENCES community (id) ON UPDATE CASCADE ON DELETE CASCADE,
published timestamptz NOT NULL DEFAULT now(),
updated timestamptz,
deleted timestamptz
);
-- indicates this tag was created by the mod of a community and can be applied to posts in this community
CREATE TABLE community_post_tag (
community_id int NOT NULL REFERENCES community (id) ON UPDATE CASCADE ON DELETE CASCADE,
tag_id int NOT NULL REFERENCES tag (id) ON UPDATE CASCADE ON DELETE CASCADE,
published timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (community_id, tag_id)
deleted boolean NOT NULL DEFAULT FALSE
);
-- an association between a post and a tag. created/updated by the post author or mods of a community