]> Untitled Git - lemmy.git/blob - crates/db_views_actor/src/community_moderator_view.rs
Merge pull request #1850 from LemmyNet/refactor-apub
[lemmy.git] / crates / db_views_actor / src / community_moderator_view.rs
1 use diesel::{result::Error, *};
2 use lemmy_db_schema::{
3   newtypes::{CommunityId, PersonId},
4   schema::{community, community_moderator, person},
5   source::{
6     community::{Community, CommunitySafe},
7     person::{Person, PersonSafe},
8   },
9   traits::{ToSafe, ViewToVec},
10 };
11 use serde::{Deserialize, Serialize};
12
13 #[derive(Debug, Serialize, Deserialize, Clone)]
14 pub struct CommunityModeratorView {
15   pub community: CommunitySafe,
16   pub moderator: PersonSafe,
17 }
18
19 type CommunityModeratorViewTuple = (CommunitySafe, PersonSafe);
20
21 impl CommunityModeratorView {
22   pub fn for_community(conn: &PgConnection, community_id: CommunityId) -> Result<Vec<Self>, Error> {
23     let res = community_moderator::table
24       .inner_join(community::table)
25       .inner_join(person::table)
26       .select((
27         Community::safe_columns_tuple(),
28         Person::safe_columns_tuple(),
29       ))
30       .filter(community_moderator::community_id.eq(community_id))
31       .order_by(community_moderator::published)
32       .load::<CommunityModeratorViewTuple>(conn)?;
33
34     Ok(Self::from_tuple_to_vec(res))
35   }
36
37   pub fn for_person(conn: &PgConnection, person_id: PersonId) -> Result<Vec<Self>, Error> {
38     let res = community_moderator::table
39       .inner_join(community::table)
40       .inner_join(person::table)
41       .select((
42         Community::safe_columns_tuple(),
43         Person::safe_columns_tuple(),
44       ))
45       .filter(community_moderator::person_id.eq(person_id))
46       .order_by(community_moderator::published)
47       .load::<CommunityModeratorViewTuple>(conn)?;
48
49     Ok(Self::from_tuple_to_vec(res))
50   }
51
52   /// Finds all communities first mods / creators
53   /// Ideally this should be a group by, but diesel doesn't support it yet
54   pub fn get_community_first_mods(conn: &PgConnection) -> Result<Vec<Self>, Error> {
55     let res = community_moderator::table
56       .inner_join(community::table)
57       .inner_join(person::table)
58       .select((
59         Community::safe_columns_tuple(),
60         Person::safe_columns_tuple(),
61       ))
62       // A hacky workaround instead of group_bys
63       // https://stackoverflow.com/questions/24042359/how-to-join-only-one-row-in-joined-table-with-postgres
64       .distinct_on(community_moderator::community_id)
65       .order_by((
66         community_moderator::community_id,
67         community_moderator::person_id,
68       ))
69       .load::<CommunityModeratorViewTuple>(conn)?;
70
71     Ok(Self::from_tuple_to_vec(res))
72   }
73 }
74
75 impl ViewToVec for CommunityModeratorView {
76   type DbTuple = CommunityModeratorViewTuple;
77   fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
78     items
79       .iter()
80       .map(|a| Self {
81         community: a.0.to_owned(),
82         moderator: a.1.to_owned(),
83       })
84       .collect::<Vec<Self>>()
85   }
86 }