]> Untitled Git - lemmy.git/blob - crates/db_queries/src/source/comment.rs
Rewrite fetcher (#1792)
[lemmy.git] / crates / db_queries / src / source / comment.rs
1 use crate::{ApubObject, Crud, DeleteableOrRemoveable, Likeable, Saveable};
2 use chrono::NaiveDateTime;
3 use diesel::{dsl::*, result::Error, *};
4 use lemmy_db_schema::{
5   naive_now,
6   source::comment::{
7     Comment,
8     CommentForm,
9     CommentLike,
10     CommentLikeForm,
11     CommentSaved,
12     CommentSavedForm,
13   },
14   CommentId,
15   DbUrl,
16   PersonId,
17 };
18
19 pub trait Comment_ {
20   fn update_ap_id(
21     conn: &PgConnection,
22     comment_id: CommentId,
23     apub_id: DbUrl,
24   ) -> Result<Comment, Error>;
25   fn permadelete_for_creator(
26     conn: &PgConnection,
27     for_creator_id: PersonId,
28   ) -> Result<Vec<Comment>, Error>;
29   fn update_deleted(
30     conn: &PgConnection,
31     comment_id: CommentId,
32     new_deleted: bool,
33   ) -> Result<Comment, Error>;
34   fn update_removed(
35     conn: &PgConnection,
36     comment_id: CommentId,
37     new_removed: bool,
38   ) -> Result<Comment, Error>;
39   fn update_removed_for_creator(
40     conn: &PgConnection,
41     for_creator_id: PersonId,
42     new_removed: bool,
43   ) -> Result<Vec<Comment>, Error>;
44   fn update_read(
45     conn: &PgConnection,
46     comment_id: CommentId,
47     new_read: bool,
48   ) -> Result<Comment, Error>;
49   fn update_content(
50     conn: &PgConnection,
51     comment_id: CommentId,
52     new_content: &str,
53   ) -> Result<Comment, Error>;
54   fn upsert(conn: &PgConnection, comment_form: &CommentForm) -> Result<Comment, Error>;
55 }
56
57 impl Comment_ for Comment {
58   fn update_ap_id(
59     conn: &PgConnection,
60     comment_id: CommentId,
61     apub_id: DbUrl,
62   ) -> Result<Self, Error> {
63     use lemmy_db_schema::schema::comment::dsl::*;
64
65     diesel::update(comment.find(comment_id))
66       .set(ap_id.eq(apub_id))
67       .get_result::<Self>(conn)
68   }
69
70   fn permadelete_for_creator(
71     conn: &PgConnection,
72     for_creator_id: PersonId,
73   ) -> Result<Vec<Self>, Error> {
74     use lemmy_db_schema::schema::comment::dsl::*;
75     diesel::update(comment.filter(creator_id.eq(for_creator_id)))
76       .set((
77         content.eq("*Permananently Deleted*"),
78         deleted.eq(true),
79         updated.eq(naive_now()),
80       ))
81       .get_results::<Self>(conn)
82   }
83
84   fn update_deleted(
85     conn: &PgConnection,
86     comment_id: CommentId,
87     new_deleted: bool,
88   ) -> Result<Self, Error> {
89     use lemmy_db_schema::schema::comment::dsl::*;
90     diesel::update(comment.find(comment_id))
91       .set((deleted.eq(new_deleted), updated.eq(naive_now())))
92       .get_result::<Self>(conn)
93   }
94
95   fn update_removed(
96     conn: &PgConnection,
97     comment_id: CommentId,
98     new_removed: bool,
99   ) -> Result<Self, Error> {
100     use lemmy_db_schema::schema::comment::dsl::*;
101     diesel::update(comment.find(comment_id))
102       .set((removed.eq(new_removed), updated.eq(naive_now())))
103       .get_result::<Self>(conn)
104   }
105
106   fn update_removed_for_creator(
107     conn: &PgConnection,
108     for_creator_id: PersonId,
109     new_removed: bool,
110   ) -> Result<Vec<Self>, Error> {
111     use lemmy_db_schema::schema::comment::dsl::*;
112     diesel::update(comment.filter(creator_id.eq(for_creator_id)))
113       .set((removed.eq(new_removed), updated.eq(naive_now())))
114       .get_results::<Self>(conn)
115   }
116
117   fn update_read(
118     conn: &PgConnection,
119     comment_id: CommentId,
120     new_read: bool,
121   ) -> Result<Self, Error> {
122     use lemmy_db_schema::schema::comment::dsl::*;
123     diesel::update(comment.find(comment_id))
124       .set(read.eq(new_read))
125       .get_result::<Self>(conn)
126   }
127
128   fn update_content(
129     conn: &PgConnection,
130     comment_id: CommentId,
131     new_content: &str,
132   ) -> Result<Self, Error> {
133     use lemmy_db_schema::schema::comment::dsl::*;
134     diesel::update(comment.find(comment_id))
135       .set((content.eq(new_content), updated.eq(naive_now())))
136       .get_result::<Self>(conn)
137   }
138
139   fn upsert(conn: &PgConnection, comment_form: &CommentForm) -> Result<Comment, Error> {
140     use lemmy_db_schema::schema::comment::dsl::*;
141     insert_into(comment)
142       .values(comment_form)
143       .on_conflict(ap_id)
144       .do_update()
145       .set(comment_form)
146       .get_result::<Self>(conn)
147   }
148 }
149
150 impl Crud for Comment {
151   type Form = CommentForm;
152   type IdType = CommentId;
153   fn read(conn: &PgConnection, comment_id: CommentId) -> Result<Self, Error> {
154     use lemmy_db_schema::schema::comment::dsl::*;
155     comment.find(comment_id).first::<Self>(conn)
156   }
157
158   fn delete(conn: &PgConnection, comment_id: CommentId) -> Result<usize, Error> {
159     use lemmy_db_schema::schema::comment::dsl::*;
160     diesel::delete(comment.find(comment_id)).execute(conn)
161   }
162
163   fn create(conn: &PgConnection, comment_form: &CommentForm) -> Result<Self, Error> {
164     use lemmy_db_schema::schema::comment::dsl::*;
165     insert_into(comment)
166       .values(comment_form)
167       .get_result::<Self>(conn)
168   }
169
170   fn update(
171     conn: &PgConnection,
172     comment_id: CommentId,
173     comment_form: &CommentForm,
174   ) -> Result<Self, Error> {
175     use lemmy_db_schema::schema::comment::dsl::*;
176     diesel::update(comment.find(comment_id))
177       .set(comment_form)
178       .get_result::<Self>(conn)
179   }
180 }
181
182 impl ApubObject for Comment {
183   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
184     None
185   }
186
187   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
188     use lemmy_db_schema::schema::comment::dsl::*;
189     comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
190   }
191 }
192
193 impl Likeable for CommentLike {
194   type Form = CommentLikeForm;
195   type IdType = CommentId;
196   fn like(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result<Self, Error> {
197     use lemmy_db_schema::schema::comment_like::dsl::*;
198     insert_into(comment_like)
199       .values(comment_like_form)
200       .on_conflict((comment_id, person_id))
201       .do_update()
202       .set(comment_like_form)
203       .get_result::<Self>(conn)
204   }
205   fn remove(
206     conn: &PgConnection,
207     person_id: PersonId,
208     comment_id: CommentId,
209   ) -> Result<usize, Error> {
210     use lemmy_db_schema::schema::comment_like::dsl;
211     diesel::delete(
212       dsl::comment_like
213         .filter(dsl::comment_id.eq(comment_id))
214         .filter(dsl::person_id.eq(person_id)),
215     )
216     .execute(conn)
217   }
218 }
219
220 impl Saveable for CommentSaved {
221   type Form = CommentSavedForm;
222   fn save(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result<Self, Error> {
223     use lemmy_db_schema::schema::comment_saved::dsl::*;
224     insert_into(comment_saved)
225       .values(comment_saved_form)
226       .on_conflict((comment_id, person_id))
227       .do_update()
228       .set(comment_saved_form)
229       .get_result::<Self>(conn)
230   }
231   fn unsave(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result<usize, Error> {
232     use lemmy_db_schema::schema::comment_saved::dsl::*;
233     diesel::delete(
234       comment_saved
235         .filter(comment_id.eq(comment_saved_form.comment_id))
236         .filter(person_id.eq(comment_saved_form.person_id)),
237     )
238     .execute(conn)
239   }
240 }
241
242 impl DeleteableOrRemoveable for Comment {
243   fn blank_out_deleted_or_removed_info(mut self) -> Self {
244     self.content = "".into();
245     self
246   }
247 }
248
249 #[cfg(test)]
250 mod tests {
251   use crate::{establish_unpooled_connection, Crud, Likeable, Saveable};
252   use lemmy_db_schema::source::{
253     comment::*,
254     community::{Community, CommunityForm},
255     person::{Person, PersonForm},
256     post::*,
257   };
258   use serial_test::serial;
259
260   #[test]
261   #[serial]
262   fn test_crud() {
263     let conn = establish_unpooled_connection();
264
265     let new_person = PersonForm {
266       name: "terry".into(),
267       ..PersonForm::default()
268     };
269
270     let inserted_person = Person::create(&conn, &new_person).unwrap();
271
272     let new_community = CommunityForm {
273       name: "test community".to_string(),
274       title: "nada".to_owned(),
275       ..CommunityForm::default()
276     };
277
278     let inserted_community = Community::create(&conn, &new_community).unwrap();
279
280     let new_post = PostForm {
281       name: "A test post".into(),
282       creator_id: inserted_person.id,
283       community_id: inserted_community.id,
284       ..PostForm::default()
285     };
286
287     let inserted_post = Post::create(&conn, &new_post).unwrap();
288
289     let comment_form = CommentForm {
290       content: "A test comment".into(),
291       creator_id: inserted_person.id,
292       post_id: inserted_post.id,
293       ..CommentForm::default()
294     };
295
296     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
297
298     let expected_comment = Comment {
299       id: inserted_comment.id,
300       content: "A test comment".into(),
301       creator_id: inserted_person.id,
302       post_id: inserted_post.id,
303       removed: false,
304       deleted: false,
305       read: false,
306       parent_id: None,
307       published: inserted_comment.published,
308       updated: None,
309       ap_id: inserted_comment.ap_id.to_owned(),
310       local: true,
311     };
312
313     let child_comment_form = CommentForm {
314       content: "A child comment".into(),
315       creator_id: inserted_person.id,
316       post_id: inserted_post.id,
317       parent_id: Some(inserted_comment.id),
318       ..CommentForm::default()
319     };
320
321     let inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
322
323     // Comment Like
324     let comment_like_form = CommentLikeForm {
325       comment_id: inserted_comment.id,
326       post_id: inserted_post.id,
327       person_id: inserted_person.id,
328       score: 1,
329     };
330
331     let inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
332
333     let expected_comment_like = CommentLike {
334       id: inserted_comment_like.id,
335       comment_id: inserted_comment.id,
336       post_id: inserted_post.id,
337       person_id: inserted_person.id,
338       published: inserted_comment_like.published,
339       score: 1,
340     };
341
342     // Comment Saved
343     let comment_saved_form = CommentSavedForm {
344       comment_id: inserted_comment.id,
345       person_id: inserted_person.id,
346     };
347
348     let inserted_comment_saved = CommentSaved::save(&conn, &comment_saved_form).unwrap();
349
350     let expected_comment_saved = CommentSaved {
351       id: inserted_comment_saved.id,
352       comment_id: inserted_comment.id,
353       person_id: inserted_person.id,
354       published: inserted_comment_saved.published,
355     };
356
357     let read_comment = Comment::read(&conn, inserted_comment.id).unwrap();
358     let updated_comment = Comment::update(&conn, inserted_comment.id, &comment_form).unwrap();
359     let like_removed = CommentLike::remove(&conn, inserted_person.id, inserted_comment.id).unwrap();
360     let saved_removed = CommentSaved::unsave(&conn, &comment_saved_form).unwrap();
361     let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();
362     Comment::delete(&conn, inserted_child_comment.id).unwrap();
363     Post::delete(&conn, inserted_post.id).unwrap();
364     Community::delete(&conn, inserted_community.id).unwrap();
365     Person::delete(&conn, inserted_person.id).unwrap();
366
367     assert_eq!(expected_comment, read_comment);
368     assert_eq!(expected_comment, inserted_comment);
369     assert_eq!(expected_comment, updated_comment);
370     assert_eq!(expected_comment_like, inserted_comment_like);
371     assert_eq!(expected_comment_saved, inserted_comment_saved);
372     assert_eq!(
373       expected_comment.id,
374       inserted_child_comment.parent_id.unwrap()
375     );
376     assert_eq!(1, like_removed);
377     assert_eq!(1, saved_removed);
378     assert_eq!(1, num_deleted);
379   }
380 }