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