]> Untitled Git - lemmy.git/blob - crates/db_views/src/local_user_view.rs
Add diesel_async, get rid of blocking function (#2510)
[lemmy.git] / crates / db_views / src / local_user_view.rs
1 use crate::structs::{LocalUserSettingsView, 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::{
9     local_user::{LocalUser, LocalUserSettings},
10     person::{Person, PersonSafe},
11   },
12   traits::{ToSafe, ToSafeSettings, ViewToVec},
13   utils::{functions::lower, get_conn, DbPool},
14 };
15
16 type LocalUserViewTuple = (LocalUser, Person, PersonAggregates);
17
18 impl LocalUserView {
19   pub async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result<Self, Error> {
20     let conn = &mut get_conn(pool).await?;
21
22     let (local_user, person, counts) = local_user::table
23       .find(local_user_id)
24       .inner_join(person::table)
25       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
26       .select((
27         local_user::all_columns,
28         person::all_columns,
29         person_aggregates::all_columns,
30       ))
31       .first::<LocalUserViewTuple>(conn)
32       .await?;
33     Ok(Self {
34       local_user,
35       person,
36       counts,
37     })
38   }
39
40   pub async fn read_person(pool: &DbPool, person_id: PersonId) -> Result<Self, Error> {
41     let conn = &mut get_conn(pool).await?;
42     let (local_user, person, counts) = local_user::table
43       .filter(person::id.eq(person_id))
44       .inner_join(person::table)
45       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
46       .select((
47         local_user::all_columns,
48         person::all_columns,
49         person_aggregates::all_columns,
50       ))
51       .first::<LocalUserViewTuple>(conn)
52       .await?;
53     Ok(Self {
54       local_user,
55       person,
56       counts,
57     })
58   }
59
60   // TODO check where this is used
61   pub async fn read_from_name(pool: &DbPool, name: &str) -> Result<Self, Error> {
62     let conn = &mut get_conn(pool).await?;
63     let (local_user, person, counts) = local_user::table
64       .filter(person::name.eq(name))
65       .inner_join(person::table)
66       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
67       .select((
68         local_user::all_columns,
69         person::all_columns,
70         person_aggregates::all_columns,
71       ))
72       .first::<LocalUserViewTuple>(conn)
73       .await?;
74     Ok(Self {
75       local_user,
76       person,
77       counts,
78     })
79   }
80
81   pub async fn find_by_email_or_name(pool: &DbPool, name_or_email: &str) -> Result<Self, Error> {
82     let conn = &mut get_conn(pool).await?;
83     let (local_user, person, counts) = local_user::table
84       .inner_join(person::table)
85       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
86       .filter(
87         lower(person::name)
88           .eq(lower(name_or_email))
89           .or(local_user::email.eq(name_or_email)),
90       )
91       .select((
92         local_user::all_columns,
93         person::all_columns,
94         person_aggregates::all_columns,
95       ))
96       .first::<LocalUserViewTuple>(conn)
97       .await?;
98     Ok(Self {
99       local_user,
100       person,
101       counts,
102     })
103   }
104
105   pub async fn find_by_email(pool: &DbPool, from_email: &str) -> Result<Self, Error> {
106     let conn = &mut get_conn(pool).await?;
107     let (local_user, person, counts) = local_user::table
108       .inner_join(person::table)
109       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
110       .filter(local_user::email.eq(from_email))
111       .select((
112         local_user::all_columns,
113         person::all_columns,
114         person_aggregates::all_columns,
115       ))
116       .first::<LocalUserViewTuple>(conn)
117       .await?;
118     Ok(Self {
119       local_user,
120       person,
121       counts,
122     })
123   }
124 }
125
126 type LocalUserSettingsViewTuple = (LocalUserSettings, PersonSafe, PersonAggregates);
127
128 impl LocalUserSettingsView {
129   pub async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result<Self, Error> {
130     let conn = &mut get_conn(pool).await?;
131     let (local_user, person, counts) = local_user::table
132       .find(local_user_id)
133       .inner_join(person::table)
134       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
135       .select((
136         LocalUser::safe_settings_columns_tuple(),
137         Person::safe_columns_tuple(),
138         person_aggregates::all_columns,
139       ))
140       .first::<LocalUserSettingsViewTuple>(conn)
141       .await?;
142     Ok(Self {
143       local_user,
144       person,
145       counts,
146     })
147   }
148
149   pub async fn list_admins_with_emails(pool: &DbPool) -> Result<Vec<Self>, Error> {
150     let conn = &mut get_conn(pool).await?;
151     let res = local_user::table
152       .filter(person::admin.eq(true))
153       .filter(local_user::email.is_not_null())
154       .inner_join(person::table)
155       .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
156       .select((
157         LocalUser::safe_settings_columns_tuple(),
158         Person::safe_columns_tuple(),
159         person_aggregates::all_columns,
160       ))
161       .load::<LocalUserSettingsViewTuple>(conn)
162       .await?;
163
164     Ok(LocalUserSettingsView::from_tuple_to_vec(res))
165   }
166 }
167
168 impl ViewToVec for LocalUserSettingsView {
169   type DbTuple = LocalUserSettingsViewTuple;
170   fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
171     items
172       .into_iter()
173       .map(|a| Self {
174         local_user: a.0,
175         person: a.1,
176         counts: a.2,
177       })
178       .collect::<Vec<Self>>()
179   }
180 }