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