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