]> Untitled Git - lemmy.git/blob - lemmy_db/src/source/post.rs
remove timing files added by accident
[lemmy.git] / lemmy_db / src / source / post.rs
1 use crate::{ApubObject, Crud, Likeable, Readable, Saveable};
2 use diesel::{dsl::*, result::Error, *};
3 use lemmy_db_schema::{
4   naive_now,
5   source::post::{
6     Post,
7     PostForm,
8     PostLike,
9     PostLikeForm,
10     PostRead,
11     PostReadForm,
12     PostSaved,
13     PostSavedForm,
14   },
15 };
16
17 impl Crud<PostForm> for Post {
18   fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
19     use lemmy_db_schema::schema::post::dsl::*;
20     post.find(post_id).first::<Self>(conn)
21   }
22
23   fn delete(conn: &PgConnection, post_id: i32) -> Result<usize, Error> {
24     use lemmy_db_schema::schema::post::dsl::*;
25     diesel::delete(post.find(post_id)).execute(conn)
26   }
27
28   fn create(conn: &PgConnection, new_post: &PostForm) -> Result<Self, Error> {
29     use lemmy_db_schema::schema::post::dsl::*;
30     insert_into(post).values(new_post).get_result::<Self>(conn)
31   }
32
33   fn update(conn: &PgConnection, post_id: i32, new_post: &PostForm) -> Result<Self, Error> {
34     use lemmy_db_schema::schema::post::dsl::*;
35     diesel::update(post.find(post_id))
36       .set(new_post)
37       .get_result::<Self>(conn)
38   }
39 }
40
41 pub trait Post_ {
42   //fn read(conn: &PgConnection, post_id: i32) -> Result<Post, Error>;
43   fn list_for_community(conn: &PgConnection, the_community_id: i32) -> Result<Vec<Post>, Error>;
44   fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Post, Error>;
45   fn permadelete_for_creator(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<Post>, Error>;
46   fn update_deleted(conn: &PgConnection, post_id: i32, new_deleted: bool) -> Result<Post, Error>;
47   fn update_removed(conn: &PgConnection, post_id: i32, new_removed: bool) -> Result<Post, Error>;
48   fn update_removed_for_creator(
49     conn: &PgConnection,
50     for_creator_id: i32,
51     for_community_id: Option<i32>,
52     new_removed: bool,
53   ) -> Result<Vec<Post>, Error>;
54   fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Post, Error>;
55   fn update_stickied(conn: &PgConnection, post_id: i32, new_stickied: bool) -> Result<Post, Error>;
56   fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool;
57 }
58
59 impl Post_ for Post {
60   // TODO: this is a duplicate?
61   //fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
62   //  use lemmy_db_schema::schema::post::dsl::*;
63   //  post.filter(id.eq(post_id)).first::<Self>(conn)
64   //}
65
66   fn list_for_community(conn: &PgConnection, the_community_id: i32) -> Result<Vec<Self>, Error> {
67     use lemmy_db_schema::schema::post::dsl::*;
68     post
69       .filter(community_id.eq(the_community_id))
70       .then_order_by(published.desc())
71       .then_order_by(stickied.desc())
72       .limit(20)
73       .load::<Self>(conn)
74   }
75
76   fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Self, Error> {
77     use lemmy_db_schema::schema::post::dsl::*;
78
79     diesel::update(post.find(post_id))
80       .set(ap_id.eq(apub_id))
81       .get_result::<Self>(conn)
82   }
83
84   fn permadelete_for_creator(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<Self>, Error> {
85     use lemmy_db_schema::schema::post::dsl::*;
86
87     let perma_deleted = "*Permananently Deleted*";
88     let perma_deleted_url = "https://deleted.com";
89
90     diesel::update(post.filter(creator_id.eq(for_creator_id)))
91       .set((
92         name.eq(perma_deleted),
93         url.eq(perma_deleted_url),
94         body.eq(perma_deleted),
95         deleted.eq(true),
96         updated.eq(naive_now()),
97       ))
98       .get_results::<Self>(conn)
99   }
100
101   fn update_deleted(conn: &PgConnection, post_id: i32, new_deleted: bool) -> Result<Self, Error> {
102     use lemmy_db_schema::schema::post::dsl::*;
103     diesel::update(post.find(post_id))
104       .set((deleted.eq(new_deleted), updated.eq(naive_now())))
105       .get_result::<Self>(conn)
106   }
107
108   fn update_removed(conn: &PgConnection, post_id: i32, new_removed: bool) -> Result<Self, Error> {
109     use lemmy_db_schema::schema::post::dsl::*;
110     diesel::update(post.find(post_id))
111       .set((removed.eq(new_removed), updated.eq(naive_now())))
112       .get_result::<Self>(conn)
113   }
114
115   fn update_removed_for_creator(
116     conn: &PgConnection,
117     for_creator_id: i32,
118     for_community_id: Option<i32>,
119     new_removed: bool,
120   ) -> Result<Vec<Self>, Error> {
121     use lemmy_db_schema::schema::post::dsl::*;
122
123     let mut update = diesel::update(post).into_boxed();
124     update = update.filter(creator_id.eq(for_creator_id));
125
126     if let Some(for_community_id) = for_community_id {
127       update = update.filter(community_id.eq(for_community_id));
128     }
129
130     update
131       .set((removed.eq(new_removed), updated.eq(naive_now())))
132       .get_results::<Self>(conn)
133   }
134
135   fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Self, Error> {
136     use lemmy_db_schema::schema::post::dsl::*;
137     diesel::update(post.find(post_id))
138       .set(locked.eq(new_locked))
139       .get_result::<Self>(conn)
140   }
141
142   fn update_stickied(conn: &PgConnection, post_id: i32, new_stickied: bool) -> Result<Self, Error> {
143     use lemmy_db_schema::schema::post::dsl::*;
144     diesel::update(post.find(post_id))
145       .set(stickied.eq(new_stickied))
146       .get_result::<Self>(conn)
147   }
148
149   fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool {
150     user_id == post_creator_id
151   }
152 }
153
154 impl ApubObject<PostForm> for Post {
155   fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
156     use lemmy_db_schema::schema::post::dsl::*;
157     post.filter(ap_id.eq(object_id)).first::<Self>(conn)
158   }
159
160   fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result<Post, Error> {
161     use lemmy_db_schema::schema::post::dsl::*;
162     insert_into(post)
163       .values(post_form)
164       .on_conflict(ap_id)
165       .do_update()
166       .set(post_form)
167       .get_result::<Self>(conn)
168   }
169 }
170
171 impl Likeable<PostLikeForm> for PostLike {
172   fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result<Self, Error> {
173     use lemmy_db_schema::schema::post_like::dsl::*;
174     insert_into(post_like)
175       .values(post_like_form)
176       .on_conflict((post_id, user_id))
177       .do_update()
178       .set(post_like_form)
179       .get_result::<Self>(conn)
180   }
181   fn remove(conn: &PgConnection, user_id: i32, post_id: i32) -> Result<usize, Error> {
182     use lemmy_db_schema::schema::post_like::dsl;
183     diesel::delete(
184       dsl::post_like
185         .filter(dsl::post_id.eq(post_id))
186         .filter(dsl::user_id.eq(user_id)),
187     )
188     .execute(conn)
189   }
190 }
191
192 impl Saveable<PostSavedForm> for PostSaved {
193   fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<Self, Error> {
194     use lemmy_db_schema::schema::post_saved::dsl::*;
195     insert_into(post_saved)
196       .values(post_saved_form)
197       .on_conflict((post_id, user_id))
198       .do_update()
199       .set(post_saved_form)
200       .get_result::<Self>(conn)
201   }
202   fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<usize, Error> {
203     use lemmy_db_schema::schema::post_saved::dsl::*;
204     diesel::delete(
205       post_saved
206         .filter(post_id.eq(post_saved_form.post_id))
207         .filter(user_id.eq(post_saved_form.user_id)),
208     )
209     .execute(conn)
210   }
211 }
212
213 impl Readable<PostReadForm> for PostRead {
214   fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<Self, Error> {
215     use lemmy_db_schema::schema::post_read::dsl::*;
216     insert_into(post_read)
217       .values(post_read_form)
218       .get_result::<Self>(conn)
219   }
220
221   fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<usize, Error> {
222     use lemmy_db_schema::schema::post_read::dsl::*;
223     diesel::delete(
224       post_read
225         .filter(post_id.eq(post_read_form.post_id))
226         .filter(user_id.eq(post_read_form.user_id)),
227     )
228     .execute(conn)
229   }
230 }
231
232 #[cfg(test)]
233 mod tests {
234   use crate::{source::post::*, tests::establish_unpooled_connection, ListingType, SortType};
235   use lemmy_db_schema::source::{
236     community::{Community, CommunityForm},
237     user::*,
238   };
239
240   #[test]
241   fn test_crud() {
242     let conn = establish_unpooled_connection();
243
244     let new_user = UserForm {
245       name: "jim".into(),
246       preferred_username: None,
247       password_encrypted: "nope".into(),
248       email: None,
249       matrix_user_id: None,
250       avatar: None,
251       banner: None,
252       admin: false,
253       banned: Some(false),
254       published: None,
255       updated: None,
256       show_nsfw: false,
257       theme: "browser".into(),
258       default_sort_type: SortType::Hot as i16,
259       default_listing_type: ListingType::Subscribed as i16,
260       lang: "browser".into(),
261       show_avatars: true,
262       send_notifications_to_email: false,
263       actor_id: None,
264       bio: None,
265       local: true,
266       private_key: None,
267       public_key: None,
268       last_refreshed_at: None,
269     };
270
271     let inserted_user = User_::create(&conn, &new_user).unwrap();
272
273     let new_community = CommunityForm {
274       name: "test community_3".to_string(),
275       title: "nada".to_owned(),
276       description: None,
277       category_id: 1,
278       creator_id: inserted_user.id,
279       removed: None,
280       deleted: None,
281       updated: None,
282       nsfw: false,
283       actor_id: None,
284       local: true,
285       private_key: None,
286       public_key: None,
287       last_refreshed_at: None,
288       published: None,
289       icon: None,
290       banner: None,
291     };
292
293     let inserted_community = Community::create(&conn, &new_community).unwrap();
294
295     let new_post = PostForm {
296       name: "A test post".into(),
297       url: None,
298       body: None,
299       creator_id: inserted_user.id,
300       community_id: inserted_community.id,
301       removed: None,
302       deleted: None,
303       locked: None,
304       stickied: None,
305       nsfw: false,
306       updated: None,
307       embed_title: None,
308       embed_description: None,
309       embed_html: None,
310       thumbnail_url: None,
311       ap_id: None,
312       local: true,
313       published: None,
314     };
315
316     let inserted_post = Post::create(&conn, &new_post).unwrap();
317
318     let expected_post = Post {
319       id: inserted_post.id,
320       name: "A test post".into(),
321       url: None,
322       body: None,
323       creator_id: inserted_user.id,
324       community_id: inserted_community.id,
325       published: inserted_post.published,
326       removed: false,
327       locked: false,
328       stickied: false,
329       nsfw: false,
330       deleted: false,
331       updated: None,
332       embed_title: None,
333       embed_description: None,
334       embed_html: None,
335       thumbnail_url: None,
336       ap_id: inserted_post.ap_id.to_owned(),
337       local: true,
338     };
339
340     // Post Like
341     let post_like_form = PostLikeForm {
342       post_id: inserted_post.id,
343       user_id: inserted_user.id,
344       score: 1,
345     };
346
347     let inserted_post_like = PostLike::like(&conn, &post_like_form).unwrap();
348
349     let expected_post_like = PostLike {
350       id: inserted_post_like.id,
351       post_id: inserted_post.id,
352       user_id: inserted_user.id,
353       published: inserted_post_like.published,
354       score: 1,
355     };
356
357     // Post Save
358     let post_saved_form = PostSavedForm {
359       post_id: inserted_post.id,
360       user_id: inserted_user.id,
361     };
362
363     let inserted_post_saved = PostSaved::save(&conn, &post_saved_form).unwrap();
364
365     let expected_post_saved = PostSaved {
366       id: inserted_post_saved.id,
367       post_id: inserted_post.id,
368       user_id: inserted_user.id,
369       published: inserted_post_saved.published,
370     };
371
372     // Post Read
373     let post_read_form = PostReadForm {
374       post_id: inserted_post.id,
375       user_id: inserted_user.id,
376     };
377
378     let inserted_post_read = PostRead::mark_as_read(&conn, &post_read_form).unwrap();
379
380     let expected_post_read = PostRead {
381       id: inserted_post_read.id,
382       post_id: inserted_post.id,
383       user_id: inserted_user.id,
384       published: inserted_post_read.published,
385     };
386
387     let read_post = Post::read(&conn, inserted_post.id).unwrap();
388     let updated_post = Post::update(&conn, inserted_post.id, &new_post).unwrap();
389     let like_removed = PostLike::remove(&conn, inserted_user.id, inserted_post.id).unwrap();
390     let saved_removed = PostSaved::unsave(&conn, &post_saved_form).unwrap();
391     let read_removed = PostRead::mark_as_unread(&conn, &post_read_form).unwrap();
392     let num_deleted = Post::delete(&conn, inserted_post.id).unwrap();
393     Community::delete(&conn, inserted_community.id).unwrap();
394     User_::delete(&conn, inserted_user.id).unwrap();
395
396     assert_eq!(expected_post, read_post);
397     assert_eq!(expected_post, inserted_post);
398     assert_eq!(expected_post, updated_post);
399     assert_eq!(expected_post_like, inserted_post_like);
400     assert_eq!(expected_post_saved, inserted_post_saved);
401     assert_eq!(expected_post_read, inserted_post_read);
402     assert_eq!(1, like_removed);
403     assert_eq!(1, saved_removed);
404     assert_eq!(1, read_removed);
405     assert_eq!(1, num_deleted);
406   }
407 }