]> Untitled Git - lemmy.git/blob - crates/db_queries/src/source/person.rs
Rewrite fetcher (#1792)
[lemmy.git] / crates / db_queries / src / source / person.rs
1 use crate::{ApubObject, Crud};
2 use chrono::NaiveDateTime;
3 use diesel::{dsl::*, result::Error, *};
4 use lemmy_db_schema::{
5   naive_now,
6   schema::person::dsl::*,
7   source::person::{Person, PersonForm},
8   DbUrl,
9   PersonId,
10 };
11
12 mod safe_type {
13   use crate::ToSafe;
14   use lemmy_db_schema::{schema::person::columns::*, source::person::Person};
15
16   type Columns = (
17     id,
18     name,
19     display_name,
20     avatar,
21     banned,
22     published,
23     updated,
24     actor_id,
25     bio,
26     local,
27     banner,
28     deleted,
29     inbox_url,
30     shared_inbox_url,
31     matrix_user_id,
32     admin,
33     bot_account,
34   );
35
36   impl ToSafe for Person {
37     type SafeColumns = Columns;
38     fn safe_columns_tuple() -> Self::SafeColumns {
39       (
40         id,
41         name,
42         display_name,
43         avatar,
44         banned,
45         published,
46         updated,
47         actor_id,
48         bio,
49         local,
50         banner,
51         deleted,
52         inbox_url,
53         shared_inbox_url,
54         matrix_user_id,
55         admin,
56         bot_account,
57       )
58     }
59   }
60 }
61
62 mod safe_type_alias_1 {
63   use crate::ToSafe;
64   use lemmy_db_schema::{schema::person_alias_1::columns::*, source::person::PersonAlias1};
65
66   type Columns = (
67     id,
68     name,
69     display_name,
70     avatar,
71     banned,
72     published,
73     updated,
74     actor_id,
75     bio,
76     local,
77     banner,
78     deleted,
79     inbox_url,
80     shared_inbox_url,
81     matrix_user_id,
82     admin,
83     bot_account,
84   );
85
86   impl ToSafe for PersonAlias1 {
87     type SafeColumns = Columns;
88     fn safe_columns_tuple() -> Self::SafeColumns {
89       (
90         id,
91         name,
92         display_name,
93         avatar,
94         banned,
95         published,
96         updated,
97         actor_id,
98         bio,
99         local,
100         banner,
101         deleted,
102         inbox_url,
103         shared_inbox_url,
104         matrix_user_id,
105         admin,
106         bot_account,
107       )
108     }
109   }
110 }
111
112 mod safe_type_alias_2 {
113   use crate::ToSafe;
114   use lemmy_db_schema::{schema::person_alias_2::columns::*, source::person::PersonAlias2};
115
116   type Columns = (
117     id,
118     name,
119     display_name,
120     avatar,
121     banned,
122     published,
123     updated,
124     actor_id,
125     bio,
126     local,
127     banner,
128     deleted,
129     inbox_url,
130     shared_inbox_url,
131     matrix_user_id,
132     admin,
133     bot_account,
134   );
135
136   impl ToSafe for PersonAlias2 {
137     type SafeColumns = Columns;
138     fn safe_columns_tuple() -> Self::SafeColumns {
139       (
140         id,
141         name,
142         display_name,
143         avatar,
144         banned,
145         published,
146         updated,
147         actor_id,
148         bio,
149         local,
150         banner,
151         deleted,
152         inbox_url,
153         shared_inbox_url,
154         matrix_user_id,
155         admin,
156         bot_account,
157       )
158     }
159   }
160 }
161
162 impl Crud for Person {
163   type Form = PersonForm;
164   type IdType = PersonId;
165   fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
166     person
167       .filter(deleted.eq(false))
168       .find(person_id)
169       .first::<Self>(conn)
170   }
171   fn delete(conn: &PgConnection, person_id: PersonId) -> Result<usize, Error> {
172     diesel::delete(person.find(person_id)).execute(conn)
173   }
174   fn create(conn: &PgConnection, form: &PersonForm) -> Result<Self, Error> {
175     insert_into(person).values(form).get_result::<Self>(conn)
176   }
177   fn update(conn: &PgConnection, person_id: PersonId, form: &PersonForm) -> Result<Self, Error> {
178     diesel::update(person.find(person_id))
179       .set(form)
180       .get_result::<Self>(conn)
181   }
182 }
183
184 impl ApubObject for Person {
185   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
186     Some(self.last_refreshed_at)
187   }
188
189   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
190     use lemmy_db_schema::schema::person::dsl::*;
191     person
192       .filter(deleted.eq(false))
193       .filter(actor_id.eq(object_id))
194       .first::<Self>(conn)
195   }
196 }
197
198 pub trait Person_ {
199   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Person, Error>;
200   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Person, Error>;
201   fn find_by_name(conn: &PgConnection, name: &str) -> Result<Person, Error>;
202   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
203   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
204   fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result<Person, Error>;
205 }
206
207 impl Person_ for Person {
208   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Self, Error> {
209     diesel::update(person.find(person_id))
210       .set(banned.eq(ban))
211       .get_result::<Self>(conn)
212   }
213
214   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Self, Error> {
215     diesel::update(person.find(person_id))
216       .set(admin.eq(added))
217       .get_result::<Self>(conn)
218   }
219
220   fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
221     person
222       .filter(deleted.eq(false))
223       .filter(local.eq(true))
224       .filter(name.ilike(from_name))
225       .first::<Person>(conn)
226   }
227
228   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
229     diesel::update(person.find(person_id))
230       .set((last_refreshed_at.eq(naive_now()),))
231       .get_result::<Self>(conn)
232   }
233
234   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
235     use lemmy_db_schema::schema::local_user;
236
237     // Set the local user info to none
238     diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
239       .set((
240         local_user::email.eq::<Option<String>>(None),
241         local_user::validator_time.eq(naive_now()),
242       ))
243       .execute(conn)?;
244
245     diesel::update(person.find(person_id))
246       .set((
247         display_name.eq::<Option<String>>(None),
248         bio.eq::<Option<String>>(None),
249         matrix_user_id.eq::<Option<String>>(None),
250         deleted.eq(true),
251         updated.eq(naive_now()),
252       ))
253       .get_result::<Self>(conn)
254   }
255
256   fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result<Person, Error> {
257     insert_into(person)
258       .values(person_form)
259       .on_conflict(actor_id)
260       .do_update()
261       .set(person_form)
262       .get_result::<Self>(conn)
263   }
264 }
265
266 #[cfg(test)]
267 mod tests {
268   use crate::{establish_unpooled_connection, source::person::*};
269
270   #[test]
271   fn test_crud() {
272     let conn = establish_unpooled_connection();
273
274     let new_person = PersonForm {
275       name: "holly".into(),
276       ..PersonForm::default()
277     };
278
279     let inserted_person = Person::create(&conn, &new_person).unwrap();
280
281     let expected_person = Person {
282       id: inserted_person.id,
283       name: "holly".into(),
284       display_name: None,
285       avatar: None,
286       banner: None,
287       banned: false,
288       deleted: false,
289       published: inserted_person.published,
290       updated: None,
291       actor_id: inserted_person.actor_id.to_owned(),
292       bio: None,
293       local: true,
294       bot_account: false,
295       admin: false,
296       private_key: None,
297       public_key: None,
298       last_refreshed_at: inserted_person.published,
299       inbox_url: inserted_person.inbox_url.to_owned(),
300       shared_inbox_url: None,
301       matrix_user_id: None,
302     };
303
304     let read_person = Person::read(&conn, inserted_person.id).unwrap();
305     let updated_person = Person::update(&conn, inserted_person.id, &new_person).unwrap();
306     let num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
307
308     assert_eq!(expected_person, read_person);
309     assert_eq!(expected_person, inserted_person);
310     assert_eq!(expected_person, updated_person);
311     assert_eq!(1, num_deleted);
312   }
313 }