X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_schema%2Fsrc%2Fimpls%2Fcommunity.rs;h=d5d558fa27adaf5e1015f7af37495ae743b0a273;hb=a47b12bbdee274c761a912cde0baddb715674023;hp=fe41d4d587247ee0d71fa4d4550731f598cf196c;hpb=165b19e75c1723bb4617ade7c28791f32d06b7ed;p=lemmy.git diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index fe41d4d5..d5d558fa 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -1,6 +1,6 @@ use crate::{ newtypes::{CommunityId, DbUrl, PersonId}, - schema::community::dsl::{actor_id, community, deleted, local, name, removed}, + schema::{community, community_follower, instance}, source::{ actor_language::CommunityLanguage, community::{ @@ -19,7 +19,18 @@ use crate::{ utils::{functions::lower, get_conn, DbPool}, SubscribedType, }; -use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods}; +use diesel::{ + deserialize, + dsl, + dsl::insert_into, + pg::Pg, + result::Error, + sql_types, + ExpressionMethods, + NullableExpressionMethods, + QueryDsl, + Queryable, +}; use diesel_async::RunQueryDsl; #[async_trait] @@ -27,29 +38,18 @@ impl Crud for Community { type InsertForm = CommunityInsertForm; type UpdateForm = CommunityUpdateForm; type IdType = CommunityId; - async fn read(pool: &DbPool, community_id: CommunityId) -> Result { - let conn = &mut get_conn(pool).await?; - community.find(community_id).first::(conn).await - } - - async fn delete(pool: &DbPool, community_id: CommunityId) -> Result { - let conn = &mut get_conn(pool).await?; - diesel::delete(community.find(community_id)) - .execute(conn) - .await - } - async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { - let conn = &mut get_conn(pool).await?; + async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result { let is_new_community = match &form.actor_id { Some(id) => Community::read_from_apub_id(pool, id).await?.is_none(), None => true, }; + let conn = &mut get_conn(pool).await?; // Can't do separate insert/update commands because InsertForm/UpdateForm aren't convertible - let community_ = insert_into(community) + let community_ = insert_into(community::table) .values(form) - .on_conflict(actor_id) + .on_conflict(community::actor_id) .do_update() .set(form) .get_result::(conn) @@ -64,12 +64,12 @@ impl Crud for Community { } async fn update( - pool: &DbPool, + pool: &mut DbPool<'_>, community_id: CommunityId, form: &Self::UpdateForm, ) -> Result { let conn = &mut get_conn(pool).await?; - diesel::update(community.find(community_id)) + diesel::update(community::table.find(community_id)) .set(form) .get_result::(conn) .await @@ -80,7 +80,7 @@ impl Crud for Community { impl Joinable for CommunityModerator { type Form = CommunityModeratorForm; async fn join( - pool: &DbPool, + pool: &mut DbPool<'_>, community_moderator_form: &CommunityModeratorForm, ) -> Result { use crate::schema::community_moderator::dsl::community_moderator; @@ -92,7 +92,7 @@ impl Joinable for CommunityModerator { } async fn leave( - pool: &DbPool, + pool: &mut DbPool<'_>, community_moderator_form: &CommunityModeratorForm, ) -> Result { use crate::schema::community_moderator::dsl::{community_id, community_moderator, person_id}; @@ -115,20 +115,20 @@ pub enum CollectionType { impl Community { /// Get the community which has a given moderators or featured url, also return the collection type pub async fn get_by_collection_url( - pool: &DbPool, + pool: &mut DbPool<'_>, url: &DbUrl, ) -> Result<(Community, CollectionType), Error> { use crate::schema::community::dsl::{featured_url, moderators_url}; use CollectionType::*; let conn = &mut get_conn(pool).await?; - let res = community + let res = community::table .filter(moderators_url.eq(url)) .first::(conn) .await; if let Ok(c) = res { return Ok((c, Moderators)); } - let res = community + let res = community::table .filter(featured_url.eq(url)) .first::(conn) .await; @@ -141,7 +141,7 @@ impl Community { impl CommunityModerator { pub async fn delete_for_community( - pool: &DbPool, + pool: &mut DbPool<'_>, for_community_id: CommunityId, ) -> Result { use crate::schema::community_moderator::dsl::{community_id, community_moderator}; @@ -152,8 +152,19 @@ impl CommunityModerator { .await } + pub async fn leave_all_communities( + pool: &mut DbPool<'_>, + for_person_id: PersonId, + ) -> Result { + use crate::schema::community_moderator::dsl::{community_moderator, person_id}; + let conn = &mut get_conn(pool).await?; + diesel::delete(community_moderator.filter(person_id.eq(for_person_id))) + .execute(conn) + .await + } + pub async fn get_person_moderated_communities( - pool: &DbPool, + pool: &mut DbPool<'_>, for_person_id: PersonId, ) -> Result, Error> { use crate::schema::community_moderator::dsl::{community_id, community_moderator, person_id}; @@ -170,7 +181,7 @@ impl CommunityModerator { impl Bannable for CommunityPersonBan { type Form = CommunityPersonBanForm; async fn ban( - pool: &DbPool, + pool: &mut DbPool<'_>, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { use crate::schema::community_person_ban::dsl::{community_id, community_person_ban, person_id}; @@ -185,7 +196,7 @@ impl Bannable for CommunityPersonBan { } async fn unban( - pool: &DbPool, + pool: &mut DbPool<'_>, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { use crate::schema::community_person_ban::dsl::{community_id, community_person_ban, person_id}; @@ -214,12 +225,27 @@ impl CommunityFollower { None => SubscribedType::NotSubscribed, } } + + pub fn select_subscribed_type() -> dsl::Nullable { + community_follower::pending.nullable() + } +} + +impl Queryable, Pg> for SubscribedType { + type Row = Option; + fn build(row: Self::Row) -> deserialize::Result { + Ok(match row { + Some(true) => SubscribedType::Pending, + Some(false) => SubscribedType::Subscribed, + None => SubscribedType::NotSubscribed, + }) + } } #[async_trait] impl Followable for CommunityFollower { type Form = CommunityFollowerForm; - async fn follow(pool: &DbPool, form: &CommunityFollowerForm) -> Result { + async fn follow(pool: &mut DbPool<'_>, form: &CommunityFollowerForm) -> Result { use crate::schema::community_follower::dsl::{community_follower, community_id, person_id}; let conn = &mut get_conn(pool).await?; insert_into(community_follower) @@ -231,7 +257,7 @@ impl Followable for CommunityFollower { .await } async fn follow_accepted( - pool: &DbPool, + pool: &mut DbPool<'_>, community_id_: CommunityId, person_id_: PersonId, ) -> Result { @@ -251,7 +277,7 @@ impl Followable for CommunityFollower { .get_result::(conn) .await } - async fn unfollow(pool: &DbPool, form: &CommunityFollowerForm) -> Result { + async fn unfollow(pool: &mut DbPool<'_>, form: &CommunityFollowerForm) -> Result { use crate::schema::community_follower::dsl::{community_follower, community_id, person_id}; let conn = &mut get_conn(pool).await?; diesel::delete( @@ -266,11 +292,14 @@ impl Followable for CommunityFollower { #[async_trait] impl ApubActor for Community { - async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result, Error> { + async fn read_from_apub_id( + pool: &mut DbPool<'_>, + object_id: &DbUrl, + ) -> Result, Error> { let conn = &mut get_conn(pool).await?; Ok( - community - .filter(actor_id.eq(object_id)) + community::table + .filter(community::actor_id.eq(object_id)) .first::(conn) .await .ok() @@ -279,30 +308,34 @@ impl ApubActor for Community { } async fn read_from_name( - pool: &DbPool, + pool: &mut DbPool<'_>, community_name: &str, include_deleted: bool, ) -> Result { let conn = &mut get_conn(pool).await?; - let mut q = community + let mut q = community::table .into_boxed() - .filter(local.eq(true)) - .filter(lower(name).eq(lower(community_name))); + .filter(community::local.eq(true)) + .filter(lower(community::name).eq(community_name.to_lowercase())); if !include_deleted { - q = q.filter(deleted.eq(false)).filter(removed.eq(false)); + q = q + .filter(community::deleted.eq(false)) + .filter(community::removed.eq(false)); } q.first::(conn).await } async fn read_from_name_and_domain( - pool: &DbPool, + pool: &mut DbPool<'_>, community_name: &str, - protocol_domain: &str, + for_domain: &str, ) -> Result { let conn = &mut get_conn(pool).await?; - community - .filter(lower(name).eq(lower(community_name))) - .filter(actor_id.like(format!("{protocol_domain}%"))) + community::table + .inner_join(instance::table) + .filter(lower(community::name).eq(community_name.to_lowercase())) + .filter(instance::domain.eq(for_domain)) + .select(community::all_columns) .first::(conn) .await } @@ -310,6 +343,9 @@ impl ApubActor for Community { #[cfg(test)] mod tests { + #![allow(clippy::unwrap_used)] + #![allow(clippy::indexing_slicing)] + use crate::{ source::{ community::{ @@ -335,6 +371,7 @@ mod tests { #[serial] async fn test_crud() { let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()) .await