]> Untitled Git - lemmy.git/blob - crates/db_views/src/local_user_view.rs
567ca3feb336e267bd675c6d179ab3480db6c2d6
[lemmy.git] / crates / db_views / src / local_user_view.rs
1 use crate::structs::LocalUserView;
2 use diesel::{result::Error, BoolExpressionMethods, ExpressionMethods, JoinOnDsl, QueryDsl};
3 use diesel_async::RunQueryDsl;
4 use lemmy_db_schema::{
5   aggregates::structs::PersonAggregates,
6   newtypes::{LocalUserId, PersonId},
7   schema::{local_user, person, person_aggregates},
8   source::{local_user::LocalUser, person::Person},
9   traits::JoinView,
10   utils::{functions::lower, get_conn, DbPool},
11 };
12
13 type LocalUserViewTuple = (LocalUser, Person, PersonAggregates);
14
15 impl LocalUserView {
16   pub async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<Self, Error> {
17     let conn = &mut get_conn(pool).await?;
18
19     let (local_user, person, counts) = local_user::table
20       .find(local_user_id)
21       .inner_join(person::table)
22       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
23       .select((
24         local_user::all_columns,
25         person::all_columns,
26         person_aggregates::all_columns,
27       ))
28       .first::<LocalUserViewTuple>(conn)
29       .await?;
30     Ok(Self {
31       local_user,
32       person,
33       counts,
34     })
35   }
36
37   pub async fn read_person(pool: &mut DbPool<'_>, person_id: PersonId) -> Result<Self, Error> {
38     let conn = &mut get_conn(pool).await?;
39     let (local_user, person, counts) = local_user::table
40       .filter(person::id.eq(person_id))
41       .inner_join(person::table)
42       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
43       .select((
44         local_user::all_columns,
45         person::all_columns,
46         person_aggregates::all_columns,
47       ))
48       .first::<LocalUserViewTuple>(conn)
49       .await?;
50     Ok(Self {
51       local_user,
52       person,
53       counts,
54     })
55   }
56
57   pub async fn read_from_name(pool: &mut DbPool<'_>, name: &str) -> Result<Self, Error> {
58     let conn = &mut get_conn(pool).await?;
59     let (local_user, person, counts) = local_user::table
60       .filter(lower(person::name).eq(name.to_lowercase()))
61       .inner_join(person::table)
62       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
63       .select((
64         local_user::all_columns,
65         person::all_columns,
66         person_aggregates::all_columns,
67       ))
68       .first::<LocalUserViewTuple>(conn)
69       .await?;
70     Ok(Self {
71       local_user,
72       person,
73       counts,
74     })
75   }
76
77   pub async fn find_by_email_or_name(
78     pool: &mut DbPool<'_>,
79     name_or_email: &str,
80   ) -> Result<Self, Error> {
81     let conn = &mut get_conn(pool).await?;
82     let (local_user, person, counts) = local_user::table
83       .inner_join(person::table)
84       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
85       .filter(
86         lower(person::name)
87           .eq(lower(name_or_email))
88           .or(local_user::email.eq(name_or_email)),
89       )
90       .select((
91         local_user::all_columns,
92         person::all_columns,
93         person_aggregates::all_columns,
94       ))
95       .first::<LocalUserViewTuple>(conn)
96       .await?;
97     Ok(Self {
98       local_user,
99       person,
100       counts,
101     })
102   }
103
104   pub async fn find_by_email(pool: &mut DbPool<'_>, from_email: &str) -> Result<Self, Error> {
105     let conn = &mut get_conn(pool).await?;
106     let (local_user, person, counts) = local_user::table
107       .inner_join(person::table)
108       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
109       .filter(local_user::email.eq(from_email))
110       .select((
111         local_user::all_columns,
112         person::all_columns,
113         person_aggregates::all_columns,
114       ))
115       .first::<LocalUserViewTuple>(conn)
116       .await?;
117     Ok(Self {
118       local_user,
119       person,
120       counts,
121     })
122   }
123
124   pub async fn list_admins_with_emails(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
125     let conn = &mut get_conn(pool).await?;
126     let res = local_user::table
127       .filter(person::admin.eq(true))
128       .filter(local_user::email.is_not_null())
129       .inner_join(person::table)
130       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
131       .select((
132         local_user::all_columns,
133         person::all_columns,
134         person_aggregates::all_columns,
135       ))
136       .load::<LocalUserViewTuple>(conn)
137       .await?;
138
139     Ok(res.into_iter().map(LocalUserView::from_tuple).collect())
140   }
141 }
142
143 impl JoinView for LocalUserView {
144   type JoinTuple = LocalUserViewTuple;
145   fn from_tuple(a: Self::JoinTuple) -> Self {
146     Self {
147       local_user: a.0,
148       person: a.1,
149       counts: a.2,
150     }
151   }
152 }