forked from LemmyNet/lemmy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Community post tags (part 1) (LemmyNet#4997)
* partial post tags implementation * fixes * fix lints * schema fix * chore: restructure / rename tag tables * chore: fix post view tests * format * lint * expect used * chore: update code to maybe final version * add ts-rs optionals * remove error context * clippy
- Loading branch information
Showing
16 changed files
with
647 additions
and
235 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use crate::{ | ||
newtypes::TagId, | ||
schema::{post_tag, tag}, | ||
source::tag::{PostTagInsertForm, Tag, TagInsertForm}, | ||
traits::Crud, | ||
utils::{get_conn, DbPool}, | ||
}; | ||
use diesel::{insert_into, result::Error, QueryDsl}; | ||
use diesel_async::RunQueryDsl; | ||
use lemmy_utils::error::LemmyResult; | ||
|
||
#[async_trait] | ||
impl Crud for Tag { | ||
type InsertForm = TagInsertForm; | ||
|
||
type UpdateForm = TagInsertForm; | ||
|
||
type IdType = TagId; | ||
|
||
async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
insert_into(tag::table) | ||
.values(form) | ||
.get_result::<Self>(conn) | ||
.await | ||
} | ||
|
||
async fn update( | ||
pool: &mut DbPool<'_>, | ||
pid: TagId, | ||
form: &Self::UpdateForm, | ||
) -> Result<Self, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
diesel::update(tag::table.find(pid)) | ||
.set(form) | ||
.get_result::<Self>(conn) | ||
.await | ||
} | ||
} | ||
|
||
impl PostTagInsertForm { | ||
pub async fn insert_tag_associations( | ||
pool: &mut DbPool<'_>, | ||
tags: &[PostTagInsertForm], | ||
) -> LemmyResult<()> { | ||
let conn = &mut get_conn(pool).await?; | ||
insert_into(post_tag::table) | ||
.values(tags) | ||
.execute(conn) | ||
.await?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use crate::newtypes::{CommunityId, DbUrl, PostId, TagId}; | ||
#[cfg(feature = "full")] | ||
use crate::schema::{post_tag, tag}; | ||
use chrono::{DateTime, Utc}; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_with::skip_serializing_none; | ||
#[cfg(feature = "full")] | ||
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))] | ||
#[cfg_attr(feature = "full", diesel(table_name = tag))] | ||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] | ||
#[cfg_attr(feature = "full", ts(export))] | ||
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>, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub updated: Option<DateTime<Utc>>, | ||
pub deleted: bool, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] | ||
#[cfg_attr(feature = "full", diesel(table_name = tag))] | ||
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: bool, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] | ||
#[cfg_attr(feature = "full", diesel(table_name = post_tag))] | ||
pub struct PostTagInsertForm { | ||
pub post_id: PostId, | ||
pub tag_id: TagId, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//! see post_view.rs for the reason for this json decoding | ||
use crate::structs::PostTags; | ||
use diesel::{ | ||
deserialize::FromSql, | ||
pg::{Pg, PgValue}, | ||
serialize::ToSql, | ||
sql_types::{self, Nullable}, | ||
}; | ||
|
||
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::<PostTags>(value)?) | ||
} | ||
fn from_nullable_sql( | ||
bytes: Option<<Pg as diesel::backend::Backend>::RawValue<'_>>, | ||
) -> diesel::deserialize::Result<Self> { | ||
match bytes { | ||
Some(bytes) => Self::from_sql(bytes), | ||
None => Ok(Self { tags: vec![] }), | ||
} | ||
} | ||
} | ||
|
||
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()) | ||
} | ||
} |
Oops, something went wrong.