]> Untitled Git - lemmy.git/blob - server/src/db/comment.rs
Spanish translations
[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_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       admin: false,
178       banned: false,
179       updated: None,
180       show_nsfw: false,
181       theme: "darkly".into(),
182     };
183
184     let inserted_user = User_::create(&conn, &new_user).unwrap();
185
186     let new_community = CommunityForm {
187       name: "test community".to_string(),
188       title: "nada".to_owned(),
189       description: None,
190       category_id: 1,
191       creator_id: inserted_user.id,
192       removed: None,
193       deleted: None,
194       updated: None,
195       nsfw: false,
196     };
197
198     let inserted_community = Community::create(&conn, &new_community).unwrap();
199
200     let new_post = PostForm {
201       name: "A test post".into(),
202       creator_id: inserted_user.id,
203       url: None,
204       body: None,
205       community_id: inserted_community.id,
206       removed: None,
207       deleted: None,
208       locked: None,
209       stickied: None,
210       updated: None,
211       nsfw: false,
212     };
213
214     let inserted_post = Post::create(&conn, &new_post).unwrap();
215
216     let comment_form = CommentForm {
217       content: "A test comment".into(),
218       creator_id: inserted_user.id,
219       post_id: inserted_post.id,
220       removed: None,
221       deleted: None,
222       read: None,
223       parent_id: None,
224       updated: None,
225     };
226
227     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
228
229     let expected_comment = Comment {
230       id: inserted_comment.id,
231       content: "A test comment".into(),
232       creator_id: inserted_user.id,
233       post_id: inserted_post.id,
234       removed: false,
235       deleted: false,
236       read: false,
237       parent_id: None,
238       published: inserted_comment.published,
239       updated: None,
240     };
241
242     let child_comment_form = CommentForm {
243       content: "A child comment".into(),
244       creator_id: inserted_user.id,
245       post_id: inserted_post.id,
246       parent_id: Some(inserted_comment.id),
247       removed: None,
248       deleted: None,
249       read: None,
250       updated: None,
251     };
252
253     let inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
254
255     // Comment Like
256     let comment_like_form = CommentLikeForm {
257       comment_id: inserted_comment.id,
258       post_id: inserted_post.id,
259       user_id: inserted_user.id,
260       score: 1,
261     };
262
263     let inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
264
265     let expected_comment_like = CommentLike {
266       id: inserted_comment_like.id,
267       comment_id: inserted_comment.id,
268       post_id: inserted_post.id,
269       user_id: inserted_user.id,
270       published: inserted_comment_like.published,
271       score: 1,
272     };
273
274     // Comment Saved
275     let comment_saved_form = CommentSavedForm {
276       comment_id: inserted_comment.id,
277       user_id: inserted_user.id,
278     };
279
280     let inserted_comment_saved = CommentSaved::save(&conn, &comment_saved_form).unwrap();
281
282     let expected_comment_saved = CommentSaved {
283       id: inserted_comment_saved.id,
284       comment_id: inserted_comment.id,
285       user_id: inserted_user.id,
286       published: inserted_comment_saved.published,
287     };
288
289     let read_comment = Comment::read(&conn, inserted_comment.id).unwrap();
290     let updated_comment = Comment::update(&conn, inserted_comment.id, &comment_form).unwrap();
291     let like_removed = CommentLike::remove(&conn, &comment_like_form).unwrap();
292     let saved_removed = CommentSaved::unsave(&conn, &comment_saved_form).unwrap();
293     let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();
294     Comment::delete(&conn, inserted_child_comment.id).unwrap();
295     Post::delete(&conn, inserted_post.id).unwrap();
296     Community::delete(&conn, inserted_community.id).unwrap();
297     User_::delete(&conn, inserted_user.id).unwrap();
298
299     assert_eq!(expected_comment, read_comment);
300     assert_eq!(expected_comment, inserted_comment);
301     assert_eq!(expected_comment, updated_comment);
302     assert_eq!(expected_comment_like, inserted_comment_like);
303     assert_eq!(expected_comment_saved, inserted_comment_saved);
304     assert_eq!(
305       expected_comment.id,
306       inserted_child_comment.parent_id.unwrap()
307     );
308     assert_eq!(1, like_removed);
309     assert_eq!(1, saved_removed);
310     assert_eq!(1, num_deleted);
311   }
312 }