]> Untitled Git - lemmy.git/blob - crates/db_views/src/local_user_view.rs
f37986cc950f0c69b0f909f724d6e7a8807616bd
[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: &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: &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: &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(pool: &DbPool, name_or_email: &str) -> Result<Self, Error> {
78     let conn = &mut get_conn(pool).await?;
79     let (local_user, person, counts) = local_user::table
80       .inner_join(person::table)
81       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
82       .filter(
83         lower(person::name)
84           .eq(lower(name_or_email))
85           .or(local_user::email.eq(name_or_email)),
86       )
87       .select((
88         local_user::all_columns,
89         person::all_columns,
90         person_aggregates::all_columns,
91       ))
92       .first::<LocalUserViewTuple>(conn)
93       .await?;
94     Ok(Self {
95       local_user,
96       person,
97       counts,
98     })
99   }
100
101   pub async fn find_by_email(pool: &DbPool, from_email: &str) -> Result<Self, Error> {
102     let conn = &mut get_conn(pool).await?;
103     let (local_user, person, counts) = local_user::table
104       .inner_join(person::table)
105       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
106       .filter(local_user::email.eq(from_email))
107       .select((
108         local_user::all_columns,
109         person::all_columns,
110         person_aggregates::all_columns,
111       ))
112       .first::<LocalUserViewTuple>(conn)
113       .await?;
114     Ok(Self {
115       local_user,
116       person,
117       counts,
118     })
119   }
120
121   pub async fn list_admins_with_emails(pool: &DbPool) -> Result<Vec<Self>, Error> {
122     let conn = &mut get_conn(pool).await?;
123     let res = local_user::table
124       .filter(person::admin.eq(true))
125       .filter(local_user::email.is_not_null())
126       .inner_join(person::table)
127       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
128       .select((
129         local_user::all_columns,
130         person::all_columns,
131         person_aggregates::all_columns,
132       ))
133       .load::<LocalUserViewTuple>(conn)
134       .await?;
135
136     Ok(res.into_iter().map(LocalUserView::from_tuple).collect())
137   }
138 }
139
140 impl JoinView for LocalUserView {
141   type JoinTuple = LocalUserViewTuple;
142   fn from_tuple(a: Self::JoinTuple) -> Self {
143     Self {
144       local_user: a.0,
145       person: a.1,
146       counts: a.2,
147     }
148   }
149 }