X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_schema%2Fsrc%2Fimpls%2Fcommunity.rs;h=258e4150442b9473de31a10583381408209f6662;hb=92568956353f21649ed9aff68b42699c9d036f30;hp=d1a4f2b6c34fa415f54105222ada626f769a948b;hpb=62663a9f2e91e3e909d96c921c21bea598a57f91;p=lemmy.git diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index d1a4f2b6..258e4150 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -1,8 +1,8 @@ use crate::{ newtypes::{CommunityId, DbUrl, PersonId}, - schema::community::dsl::{actor_id, community, deleted, local, name, removed}, + schema::{community, instance}, source::{ - actor_language::{CommunityLanguage, SiteLanguage}, + actor_language::CommunityLanguage, community::{ Community, CommunityFollower, @@ -12,118 +12,54 @@ use crate::{ CommunityModeratorForm, CommunityPersonBan, CommunityPersonBanForm, - CommunitySafe, CommunityUpdateForm, }, }, - traits::{ApubActor, Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable}, + traits::{ApubActor, Bannable, Crud, Followable, Joinable}, utils::{functions::lower, get_conn, DbPool}, SubscribedType, }; -use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods}; +use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl}; use diesel_async::RunQueryDsl; -mod safe_type { - use crate::{ - schema::community::{ - actor_id, - banner, - deleted, - description, - hidden, - icon, - id, - instance_id, - local, - name, - nsfw, - posting_restricted_to_mods, - published, - removed, - title, - updated, - }, - source::community::Community, - traits::ToSafe, - }; - - type Columns = ( - id, - name, - title, - description, - removed, - published, - updated, - deleted, - nsfw, - actor_id, - local, - icon, - banner, - hidden, - posting_restricted_to_mods, - instance_id, - ); - - impl ToSafe for Community { - type SafeColumns = Columns; - fn safe_columns_tuple() -> Self::SafeColumns { - ( - id, - name, - title, - description, - removed, - published, - updated, - deleted, - nsfw, - actor_id, - local, - icon, - banner, - hidden, - posting_restricted_to_mods, - instance_id, - ) - } - } -} - #[async_trait] impl Crud for Community { type InsertForm = CommunityInsertForm; type UpdateForm = CommunityUpdateForm; type IdType = CommunityId; - async fn read(pool: &DbPool, community_id: CommunityId) -> Result { + async fn read(pool: &mut DbPool<'_>, community_id: CommunityId) -> Result { let conn = &mut get_conn(pool).await?; - community.find(community_id).first::(conn).await + community::table + .find(community_id) + .first::(conn) + .await } - async fn delete(pool: &DbPool, community_id: CommunityId) -> Result { + async fn delete(pool: &mut DbPool<'_>, community_id: CommunityId) -> Result { let conn = &mut get_conn(pool).await?; - diesel::delete(community.find(community_id)) + diesel::delete(community::table.find(community_id)) .execute(conn) .await } - async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + 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?; - let community_ = insert_into(community) + + // Can't do separate insert/update commands because InsertForm/UpdateForm aren't convertible + let community_ = insert_into(community::table) .values(form) - .on_conflict(actor_id) + .on_conflict(community::actor_id) .do_update() .set(form) .get_result::(conn) .await?; - let site_languages = SiteLanguage::read_local(pool).await; - if let Ok(langs) = site_languages { - // if site exists, init user with site languages - CommunityLanguage::update(pool, langs, community_.id).await?; - } else { - // otherwise, init with all languages (this only happens during tests) + // Initialize languages for new community + if is_new_community { CommunityLanguage::update(pool, vec![], community_.id).await?; } @@ -131,12 +67,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 @@ -147,7 +83,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; @@ -159,7 +95,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}; @@ -174,26 +110,6 @@ impl Joinable for CommunityModerator { } } -impl DeleteableOrRemoveable for CommunitySafe { - fn blank_out_deleted_or_removed_info(mut self) -> Self { - self.title = String::new(); - self.description = None; - self.icon = None; - self.banner = None; - self - } -} - -impl DeleteableOrRemoveable for Community { - fn blank_out_deleted_or_removed_info(mut self) -> Self { - self.title = String::new(); - self.description = None; - self.icon = None; - self.banner = None; - self - } -} - pub enum CollectionType { Moderators, Featured, @@ -202,20 +118,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; @@ -228,7 +144,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}; @@ -239,8 +155,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}; @@ -257,7 +184,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}; @@ -272,7 +199,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}; @@ -306,7 +233,7 @@ impl CommunityFollower { #[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) @@ -318,7 +245,7 @@ impl Followable for CommunityFollower { .await } async fn follow_accepted( - pool: &DbPool, + pool: &mut DbPool<'_>, community_id_: CommunityId, person_id_: PersonId, ) -> Result { @@ -338,7 +265,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( @@ -353,11 +280,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() @@ -366,30 +296,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 } @@ -397,6 +331,9 @@ impl ApubActor for Community { #[cfg(test)] mod tests { + #![allow(clippy::unwrap_used)] + #![allow(clippy::indexing_slicing)] + use crate::{ source::{ community::{ @@ -422,8 +359,11 @@ mod tests { #[serial] async fn test_crud() { let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); - let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); + let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()) + .await + .unwrap(); let new_person = PersonInsertForm::builder() .name("bobbee".into())