mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-22 19:01:32 +00:00
chore: update code to maybe final version
This commit is contained in:
parent
fcd7c6d0eb
commit
03b850ed75
10 changed files with 52 additions and 133 deletions
|
@ -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<'_>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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)]
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE post_tag;
|
||||
|
||||
DROP TABLE community_post_tag;
|
||||
|
||||
DROP TABLE tag;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue