3 schema::{post, post_like, post_read, post_saved},
10 use diesel::{dsl::*, result::Error, *};
12 use url::{ParseError, Url};
14 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
15 #[table_name = "post"]
19 pub url: Option<String>,
20 pub body: Option<String>,
22 pub community_id: i32,
25 pub published: chrono::NaiveDateTime,
26 pub updated: Option<chrono::NaiveDateTime>,
30 pub embed_title: Option<String>,
31 pub embed_description: Option<String>,
32 pub embed_html: Option<String>,
33 pub thumbnail_url: Option<String>,
38 #[derive(Insertable, AsChangeset)]
39 #[table_name = "post"]
42 pub url: Option<String>,
43 pub body: Option<String>,
45 pub community_id: i32,
46 pub removed: Option<bool>,
47 pub locked: Option<bool>,
48 pub published: Option<chrono::NaiveDateTime>,
49 pub updated: Option<chrono::NaiveDateTime>,
50 pub deleted: Option<bool>,
52 pub stickied: Option<bool>,
53 pub embed_title: Option<String>,
54 pub embed_description: Option<String>,
55 pub embed_html: Option<String>,
56 pub thumbnail_url: Option<String>,
57 pub ap_id: Option<String>,
62 pub fn get_ap_id(&self) -> Result<Url, ParseError> {
63 Url::parse(&self.ap_id.as_ref().unwrap_or(&"not_a_url".to_string()))
67 impl Crud<PostForm> for Post {
68 fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
69 use crate::schema::post::dsl::*;
70 post.find(post_id).first::<Self>(conn)
73 fn delete(conn: &PgConnection, post_id: i32) -> Result<usize, Error> {
74 use crate::schema::post::dsl::*;
75 diesel::delete(post.find(post_id)).execute(conn)
78 fn create(conn: &PgConnection, new_post: &PostForm) -> Result<Self, Error> {
79 use crate::schema::post::dsl::*;
80 insert_into(post).values(new_post).get_result::<Self>(conn)
83 fn update(conn: &PgConnection, post_id: i32, new_post: &PostForm) -> Result<Self, Error> {
84 use crate::schema::post::dsl::*;
85 diesel::update(post.find(post_id))
87 .get_result::<Self>(conn)
91 impl ApubObject<PostForm> for Post {
92 fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
93 use crate::schema::post::dsl::*;
94 post.filter(ap_id.eq(object_id)).first::<Self>(conn)
97 fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result<Post, Error> {
98 use crate::schema::post::dsl::*;
104 .get_result::<Self>(conn)
109 pub fn list_for_community(
111 the_community_id: i32,
112 ) -> Result<Vec<Self>, Error> {
113 use crate::schema::post::dsl::*;
115 .filter(community_id.eq(the_community_id))
116 .then_order_by(published.desc())
117 .then_order_by(stickied.desc())
122 pub fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Self, Error> {
123 use crate::schema::post::dsl::*;
125 diesel::update(post.find(post_id))
126 .set(ap_id.eq(apub_id))
127 .get_result::<Self>(conn)
130 pub fn permadelete_for_creator(
133 ) -> Result<Vec<Self>, Error> {
134 use crate::schema::post::dsl::*;
136 let perma_deleted = "*Permananently Deleted*";
137 let perma_deleted_url = "https://deleted.com";
139 diesel::update(post.filter(creator_id.eq(for_creator_id)))
141 name.eq(perma_deleted),
142 url.eq(perma_deleted_url),
143 body.eq(perma_deleted),
145 updated.eq(naive_now()),
147 .get_results::<Self>(conn)
150 pub fn update_deleted(
154 ) -> Result<Self, Error> {
155 use crate::schema::post::dsl::*;
156 diesel::update(post.find(post_id))
157 .set((deleted.eq(new_deleted), updated.eq(naive_now())))
158 .get_result::<Self>(conn)
161 pub fn update_removed(
165 ) -> Result<Self, Error> {
166 use crate::schema::post::dsl::*;
167 diesel::update(post.find(post_id))
168 .set((removed.eq(new_removed), updated.eq(naive_now())))
169 .get_result::<Self>(conn)
172 pub fn update_removed_for_creator(
175 for_community_id: Option<i32>,
177 ) -> Result<Vec<Self>, Error> {
178 use crate::schema::post::dsl::*;
180 let mut update = diesel::update(post).into_boxed();
181 update = update.filter(creator_id.eq(for_creator_id));
183 if let Some(for_community_id) = for_community_id {
184 update = update.filter(community_id.eq(for_community_id));
188 .set((removed.eq(new_removed), updated.eq(naive_now())))
189 .get_results::<Self>(conn)
192 pub fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Self, Error> {
193 use crate::schema::post::dsl::*;
194 diesel::update(post.find(post_id))
195 .set(locked.eq(new_locked))
196 .get_result::<Self>(conn)
199 pub fn update_stickied(
203 ) -> Result<Self, Error> {
204 use crate::schema::post::dsl::*;
205 diesel::update(post.find(post_id))
206 .set(stickied.eq(new_stickied))
207 .get_result::<Self>(conn)
210 pub fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool {
211 user_id == post_creator_id
215 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
217 #[table_name = "post_like"]
218 pub struct PostLike {
223 pub published: chrono::NaiveDateTime,
226 #[derive(Insertable, AsChangeset, Clone)]
227 #[table_name = "post_like"]
228 pub struct PostLikeForm {
234 impl Likeable<PostLikeForm> for PostLike {
235 fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result<Self, Error> {
236 use crate::schema::post_like::dsl::*;
237 insert_into(post_like)
238 .values(post_like_form)
239 .on_conflict((post_id, user_id))
242 .get_result::<Self>(conn)
244 fn remove(conn: &PgConnection, user_id: i32, post_id: i32) -> Result<usize, Error> {
245 use crate::schema::post_like::dsl;
248 .filter(dsl::post_id.eq(post_id))
249 .filter(dsl::user_id.eq(user_id)),
255 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
257 #[table_name = "post_saved"]
258 pub struct PostSaved {
262 pub published: chrono::NaiveDateTime,
265 #[derive(Insertable, AsChangeset)]
266 #[table_name = "post_saved"]
267 pub struct PostSavedForm {
272 impl Saveable<PostSavedForm> for PostSaved {
273 fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<Self, Error> {
274 use crate::schema::post_saved::dsl::*;
275 insert_into(post_saved)
276 .values(post_saved_form)
277 .on_conflict((post_id, user_id))
279 .set(post_saved_form)
280 .get_result::<Self>(conn)
282 fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<usize, Error> {
283 use crate::schema::post_saved::dsl::*;
286 .filter(post_id.eq(post_saved_form.post_id))
287 .filter(user_id.eq(post_saved_form.user_id)),
293 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
295 #[table_name = "post_read"]
296 pub struct PostRead {
303 pub published: chrono::NaiveDateTime,
306 #[derive(Insertable, AsChangeset)]
307 #[table_name = "post_read"]
308 pub struct PostReadForm {
314 impl Readable<PostReadForm> for PostRead {
315 fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<Self, Error> {
316 use crate::schema::post_read::dsl::*;
317 insert_into(post_read)
318 .values(post_read_form)
319 .get_result::<Self>(conn)
322 fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<usize, Error> {
323 use crate::schema::post_read::dsl::*;
326 .filter(post_id.eq(post_read_form.post_id))
327 .filter(user_id.eq(post_read_form.user_id)),
336 source::{community::*, post::*, user::*},
337 tests::establish_unpooled_connection,
344 let conn = establish_unpooled_connection();
346 let new_user = UserForm {
348 preferred_username: None,
349 password_encrypted: "nope".into(),
351 matrix_user_id: None,
359 theme: "browser".into(),
360 default_sort_type: SortType::Hot as i16,
361 default_listing_type: ListingType::Subscribed as i16,
362 lang: "browser".into(),
364 send_notifications_to_email: false,
370 last_refreshed_at: None,
373 let inserted_user = User_::create(&conn, &new_user).unwrap();
375 let new_community = CommunityForm {
376 name: "test community_3".to_string(),
377 title: "nada".to_owned(),
380 creator_id: inserted_user.id,
389 last_refreshed_at: None,
395 let inserted_community = Community::create(&conn, &new_community).unwrap();
397 let new_post = PostForm {
398 name: "A test post".into(),
401 creator_id: inserted_user.id,
402 community_id: inserted_community.id,
410 embed_description: None,
418 let inserted_post = Post::create(&conn, &new_post).unwrap();
420 let expected_post = Post {
421 id: inserted_post.id,
422 name: "A test post".into(),
425 creator_id: inserted_user.id,
426 community_id: inserted_community.id,
427 published: inserted_post.published,
435 embed_description: None,
438 ap_id: inserted_post.ap_id.to_owned(),
443 let post_like_form = PostLikeForm {
444 post_id: inserted_post.id,
445 user_id: inserted_user.id,
449 let inserted_post_like = PostLike::like(&conn, &post_like_form).unwrap();
451 let expected_post_like = PostLike {
452 id: inserted_post_like.id,
453 post_id: inserted_post.id,
454 user_id: inserted_user.id,
455 published: inserted_post_like.published,
460 let post_saved_form = PostSavedForm {
461 post_id: inserted_post.id,
462 user_id: inserted_user.id,
465 let inserted_post_saved = PostSaved::save(&conn, &post_saved_form).unwrap();
467 let expected_post_saved = PostSaved {
468 id: inserted_post_saved.id,
469 post_id: inserted_post.id,
470 user_id: inserted_user.id,
471 published: inserted_post_saved.published,
475 let post_read_form = PostReadForm {
476 post_id: inserted_post.id,
477 user_id: inserted_user.id,
480 let inserted_post_read = PostRead::mark_as_read(&conn, &post_read_form).unwrap();
482 let expected_post_read = PostRead {
483 id: inserted_post_read.id,
484 post_id: inserted_post.id,
485 user_id: inserted_user.id,
486 published: inserted_post_read.published,
489 let read_post = Post::read(&conn, inserted_post.id).unwrap();
490 let updated_post = Post::update(&conn, inserted_post.id, &new_post).unwrap();
491 let like_removed = PostLike::remove(&conn, inserted_user.id, inserted_post.id).unwrap();
492 let saved_removed = PostSaved::unsave(&conn, &post_saved_form).unwrap();
493 let read_removed = PostRead::mark_as_unread(&conn, &post_read_form).unwrap();
494 let num_deleted = Post::delete(&conn, inserted_post.id).unwrap();
495 Community::delete(&conn, inserted_community.id).unwrap();
496 User_::delete(&conn, inserted_user.id).unwrap();
498 assert_eq!(expected_post, read_post);
499 assert_eq!(expected_post, inserted_post);
500 assert_eq!(expected_post, updated_post);
501 assert_eq!(expected_post_like, inserted_post_like);
502 assert_eq!(expected_post_saved, inserted_post_saved);
503 assert_eq!(expected_post_read, inserted_post_read);
504 assert_eq!(1, like_removed);
505 assert_eq!(1, saved_removed);
506 assert_eq!(1, read_removed);
507 assert_eq!(1, num_deleted);