]> Untitled Git - lemmy.git/blob - server/src/db/comment.rs
Merge branch 'admin_settings' into dev
[lemmy.git] / server / src / db / comment.rs
1 use super::post::Post;
2 use super::*;
3 use crate::schema::{comment, comment_like, comment_saved};
4
5 // WITH RECURSIVE MyTree AS (
6 //     SELECT * FROM comment WHERE parent_id IS NULL
7 //     UNION ALL
8 //     SELECT m.* FROM comment AS m JOIN MyTree AS t ON m.parent_id = t.id
9 // )
10 // SELECT * FROM MyTree;
11
12 #[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
13 #[belongs_to(Post)]
14 #[table_name = "comment"]
15 pub struct Comment {
16   pub id: i32,
17   pub creator_id: i32,
18   pub post_id: i32,
19   pub parent_id: Option<i32>,
20   pub content: String,
21   pub removed: bool,
22   pub read: bool,
23   pub published: chrono::NaiveDateTime,
24   pub updated: Option<chrono::NaiveDateTime>,
25   pub deleted: bool,
26 }
27
28 #[derive(Insertable, AsChangeset, Clone)]
29 #[table_name = "comment"]
30 pub struct CommentForm {
31   pub creator_id: i32,
32   pub post_id: i32,
33   pub parent_id: Option<i32>,
34   pub content: String,
35   pub removed: Option<bool>,
36   pub read: Option<bool>,
37   pub updated: Option<chrono::NaiveDateTime>,
38   pub deleted: Option<bool>,
39 }
40
41 impl Crud<CommentForm> for Comment {
42   fn read(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
43     use crate::schema::comment::dsl::*;
44     comment.find(comment_id).first::<Self>(conn)
45   }
46
47   fn delete(conn: &PgConnection, comment_id: i32) -> Result<usize, Error> {
48     use crate::schema::comment::dsl::*;
49     diesel::delete(comment.find(comment_id)).execute(conn)
50   }
51
52   fn create(conn: &PgConnection, comment_form: &CommentForm) -> Result<Self, Error> {
53     use crate::schema::comment::dsl::*;
54     insert_into(comment)
55       .values(comment_form)
56       .get_result::<Self>(conn)
57   }
58
59   fn update(
60     conn: &PgConnection,
61     comment_id: i32,
62     comment_form: &CommentForm,
63   ) -> Result<Self, Error> {
64     use crate::schema::comment::dsl::*;
65     diesel::update(comment.find(comment_id))
66       .set(comment_form)
67       .get_result::<Self>(conn)
68   }
69 }
70
71 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]
72 #[belongs_to(Comment)]
73 #[table_name = "comment_like"]
74 pub struct CommentLike {
75   pub id: i32,
76   pub user_id: i32,
77   pub comment_id: i32,
78   pub post_id: i32,
79   pub score: i16,
80   pub published: chrono::NaiveDateTime,
81 }
82
83 #[derive(Insertable, AsChangeset, Clone)]
84 #[table_name = "comment_like"]
85 pub struct CommentLikeForm {
86   pub user_id: i32,
87   pub comment_id: i32,
88   pub post_id: i32,
89   pub score: i16,
90 }
91
92 impl Likeable<CommentLikeForm> for CommentLike {
93   fn read(conn: &PgConnection, comment_id_from: i32) -> Result<Vec<Self>, Error> {
94     use crate::schema::comment_like::dsl::*;
95     comment_like
96       .filter(comment_id.eq(comment_id_from))
97       .load::<Self>(conn)
98   }
99
100   fn like(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result<Self, Error> {
101     use crate::schema::comment_like::dsl::*;
102     insert_into(comment_like)
103       .values(comment_like_form)
104       .get_result::<Self>(conn)
105   }
106   fn remove(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result<usize, Error> {
107     use crate::schema::comment_like::dsl::*;
108     diesel::delete(
109       comment_like
110         .filter(comment_id.eq(comment_like_form.comment_id))
111         .filter(user_id.eq(comment_like_form.user_id)),
112     )
113     .execute(conn)
114   }
115 }
116
117 impl CommentLike {
118   pub fn from_post(conn: &PgConnection, post_id_from: i32) -> Result<Vec<Self>, Error> {
119     use crate::schema::comment_like::dsl::*;
120     comment_like
121       .filter(post_id.eq(post_id_from))
122       .load::<Self>(conn)
123   }
124 }
125
126 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
127 #[belongs_to(Comment)]
128 #[table_name = "comment_saved"]
129 pub struct CommentSaved {
130   pub id: i32,
131   pub comment_id: i32,
132   pub user_id: i32,
133   pub published: chrono::NaiveDateTime,
134 }
135
136 #[derive(Insertable, AsChangeset, Clone)]
137 #[table_name = "comment_saved"]
138 pub struct CommentSavedForm {
139   pub comment_id: i32,
140   pub user_id: i32,
141 }
142
143 impl Saveable<CommentSavedForm> for CommentSaved {
144   fn save(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result<Self, Error> {
145     use crate::schema::comment_saved::dsl::*;
146     insert_into(comment_saved)
147       .values(comment_saved_form)
148       .get_result::<Self>(conn)
149   }
150   fn unsave(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result<usize, Error> {
151     use crate::schema::comment_saved::dsl::*;
152     diesel::delete(
153       comment_saved
154         .filter(comment_id.eq(comment_saved_form.comment_id))
155         .filter(user_id.eq(comment_saved_form.user_id)),
156     )
157     .execute(conn)
158   }
159 }
160
161 #[cfg(test)]
162 mod tests {
163   use super::super::community::*;
164   use super::super::post::*;
165   use super::super::user::*;
166   use super::*;
167   #[test]
168   fn test_crud() {
169     let conn = establish_unpooled_connection();
170
171     let new_user = UserForm {
172       name: "terry".into(),
173       fedi_name: "rrf".into(),
174       preferred_username: None,
175       password_encrypted: "nope".into(),
176       email: None,
177       matrix_user_id: None,
178       avatar: None,
179       admin: false,
180       banned: false,
181       updated: None,
182       show_nsfw: false,
183       theme: "darkly".into(),
184       default_sort_type: SortType::Hot as i16,
185       default_listing_type: ListingType::Subscribed as i16,
186       lang: "browser".into(),
187       show_avatars: true,
188       send_notifications_to_email: false,
189     };
190
191     let inserted_user = User_::create(&conn, &new_user).unwrap();
192
193     let new_community = CommunityForm {
194       name: "test community".to_string(),
195       title: "nada".to_owned(),
196       description: None,
197       category_id: 1,
198       creator_id: inserted_user.id,
199       removed: None,
200       deleted: None,
201       updated: None,
202       nsfw: false,
203     };
204
205     let inserted_community = Community::create(&conn, &new_community).unwrap();
206
207     let new_post = PostForm {
208       name: "A test post".into(),
209       creator_id: inserted_user.id,
210       url: None,
211       body: None,
212       community_id: inserted_community.id,
213       removed: None,
214       deleted: None,
215       locked: None,
216       stickied: None,
217       updated: None,
218       nsfw: false,
219       embed_title: None,
220       embed_description: None,
221       embed_html: None,
222       thumbnail_url: None,
223     };
224
225     let inserted_post = Post::create(&conn, &new_post).unwrap();
226
227     let comment_form = CommentForm {
228       content: "A test comment".into(),
229       creator_id: inserted_user.id,
230       post_id: inserted_post.id,
231       removed: None,
232       deleted: None,
233       read: None,
234       parent_id: None,
235       updated: None,
236     };
237
238     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
239
240     let expected_comment = Comment {
241       id: inserted_comment.id,
242       content: "A test comment".into(),
243       creator_id: inserted_user.id,
244       post_id: inserted_post.id,
245       removed: false,
246       deleted: false,
247       read: false,
248       parent_id: None,
249       published: inserted_comment.published,
250       updated: None,
251     };
252
253     let child_comment_form = CommentForm {
254       content: "A child comment".into(),
255       creator_id: inserted_user.id,
256       post_id: inserted_post.id,
257       parent_id: Some(inserted_comment.id),
258       removed: None,
259       deleted: None,
260       read: None,
261       updated: None,
262     };
263
264     let inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
265
266     // Comment Like
267     let comment_like_form = CommentLikeForm {
268       comment_id: inserted_comment.id,
269       post_id: inserted_post.id,
270       user_id: inserted_user.id,
271       score: 1,
272     };
273
274     let inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
275
276     let expected_comment_like = CommentLike {
277       id: inserted_comment_like.id,
278       comment_id: inserted_comment.id,
279       post_id: inserted_post.id,
280       user_id: inserted_user.id,
281       published: inserted_comment_like.published,
282       score: 1,
283     };
284
285     // Comment Saved
286     let comment_saved_form = CommentSavedForm {
287       comment_id: inserted_comment.id,
288       user_id: inserted_user.id,
289     };
290
291     let inserted_comment_saved = CommentSaved::save(&conn, &comment_saved_form).unwrap();
292
293     let expected_comment_saved = CommentSaved {
294       id: inserted_comment_saved.id,
295       comment_id: inserted_comment.id,
296       user_id: inserted_user.id,
297       published: inserted_comment_saved.published,
298     };
299
300     let read_comment = Comment::read(&conn, inserted_comment.id).unwrap();
301     let updated_comment = Comment::update(&conn, inserted_comment.id, &comment_form).unwrap();
302     let like_removed = CommentLike::remove(&conn, &comment_like_form).unwrap();
303     let saved_removed = CommentSaved::unsave(&conn, &comment_saved_form).unwrap();
304     let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();
305     Comment::delete(&conn, inserted_child_comment.id).unwrap();
306     Post::delete(&conn, inserted_post.id).unwrap();
307     Community::delete(&conn, inserted_community.id).unwrap();
308     User_::delete(&conn, inserted_user.id).unwrap();
309
310     assert_eq!(expected_comment, read_comment);
311     assert_eq!(expected_comment, inserted_comment);
312     assert_eq!(expected_comment, updated_comment);
313     assert_eq!(expected_comment_like, inserted_comment_like);
314     assert_eq!(expected_comment_saved, inserted_comment_saved);
315     assert_eq!(
316       expected_comment.id,
317       inserted_child_comment.parent_id.unwrap()
318     );
319     assert_eq!(1, like_removed);
320     assert_eq!(1, saved_removed);
321     assert_eq!(1, num_deleted);
322   }
323 }