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 read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
110 use crate::schema::post::dsl::*;
111 post.filter(id.eq(post_id)).first::<Self>(conn)
114 pub fn list_for_community(
116 the_community_id: i32,
117 ) -> Result<Vec<Self>, Error> {
118 use crate::schema::post::dsl::*;
120 .filter(community_id.eq(the_community_id))
121 .then_order_by(published.desc())
122 .then_order_by(stickied.desc())
127 pub fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Self, Error> {
128 use crate::schema::post::dsl::*;
130 diesel::update(post.find(post_id))
131 .set(ap_id.eq(apub_id))
132 .get_result::<Self>(conn)
135 pub fn permadelete_for_creator(
138 ) -> Result<Vec<Self>, Error> {
139 use crate::schema::post::dsl::*;
141 let perma_deleted = "*Permananently Deleted*";
142 let perma_deleted_url = "https://deleted.com";
144 diesel::update(post.filter(creator_id.eq(for_creator_id)))
146 name.eq(perma_deleted),
147 url.eq(perma_deleted_url),
148 body.eq(perma_deleted),
150 updated.eq(naive_now()),
152 .get_results::<Self>(conn)
155 pub fn update_deleted(
159 ) -> Result<Self, Error> {
160 use crate::schema::post::dsl::*;
161 diesel::update(post.find(post_id))
162 .set((deleted.eq(new_deleted), updated.eq(naive_now())))
163 .get_result::<Self>(conn)
166 pub fn update_removed(
170 ) -> Result<Self, Error> {
171 use crate::schema::post::dsl::*;
172 diesel::update(post.find(post_id))
173 .set((removed.eq(new_removed), updated.eq(naive_now())))
174 .get_result::<Self>(conn)
177 pub fn update_removed_for_creator(
180 for_community_id: Option<i32>,
182 ) -> Result<Vec<Self>, Error> {
183 use crate::schema::post::dsl::*;
185 let mut update = diesel::update(post).into_boxed();
186 update = update.filter(creator_id.eq(for_creator_id));
188 if let Some(for_community_id) = for_community_id {
189 update = update.filter(community_id.eq(for_community_id));
193 .set((removed.eq(new_removed), updated.eq(naive_now())))
194 .get_results::<Self>(conn)
197 pub fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Self, Error> {
198 use crate::schema::post::dsl::*;
199 diesel::update(post.find(post_id))
200 .set(locked.eq(new_locked))
201 .get_result::<Self>(conn)
204 pub fn update_stickied(
208 ) -> Result<Self, Error> {
209 use crate::schema::post::dsl::*;
210 diesel::update(post.find(post_id))
211 .set(stickied.eq(new_stickied))
212 .get_result::<Self>(conn)
215 pub fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool {
216 user_id == post_creator_id
220 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
222 #[table_name = "post_like"]
223 pub struct PostLike {
228 pub published: chrono::NaiveDateTime,
231 #[derive(Insertable, AsChangeset, Clone)]
232 #[table_name = "post_like"]
233 pub struct PostLikeForm {
239 impl Likeable<PostLikeForm> for PostLike {
240 fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result<Self, Error> {
241 use crate::schema::post_like::dsl::*;
242 insert_into(post_like)
243 .values(post_like_form)
244 .on_conflict((post_id, user_id))
247 .get_result::<Self>(conn)
249 fn remove(conn: &PgConnection, user_id: i32, post_id: i32) -> Result<usize, Error> {
250 use crate::schema::post_like::dsl;
253 .filter(dsl::post_id.eq(post_id))
254 .filter(dsl::user_id.eq(user_id)),
260 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
262 #[table_name = "post_saved"]
263 pub struct PostSaved {
267 pub published: chrono::NaiveDateTime,
270 #[derive(Insertable, AsChangeset)]
271 #[table_name = "post_saved"]
272 pub struct PostSavedForm {
277 impl Saveable<PostSavedForm> for PostSaved {
278 fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<Self, Error> {
279 use crate::schema::post_saved::dsl::*;
280 insert_into(post_saved)
281 .values(post_saved_form)
282 .on_conflict((post_id, user_id))
284 .set(post_saved_form)
285 .get_result::<Self>(conn)
287 fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<usize, Error> {
288 use crate::schema::post_saved::dsl::*;
291 .filter(post_id.eq(post_saved_form.post_id))
292 .filter(user_id.eq(post_saved_form.user_id)),
298 #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
300 #[table_name = "post_read"]
301 pub struct PostRead {
308 pub published: chrono::NaiveDateTime,
311 #[derive(Insertable, AsChangeset)]
312 #[table_name = "post_read"]
313 pub struct PostReadForm {
319 impl Readable<PostReadForm> for PostRead {
320 fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<Self, Error> {
321 use crate::schema::post_read::dsl::*;
322 insert_into(post_read)
323 .values(post_read_form)
324 .get_result::<Self>(conn)
327 fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<usize, Error> {
328 use crate::schema::post_read::dsl::*;
331 .filter(post_id.eq(post_read_form.post_id))
332 .filter(user_id.eq(post_read_form.user_id)),
341 source::{community::*, post::*, user::*},
342 tests::establish_unpooled_connection,
349 let conn = establish_unpooled_connection();
351 let new_user = UserForm {
353 preferred_username: None,
354 password_encrypted: "nope".into(),
356 matrix_user_id: None,
364 theme: "browser".into(),
365 default_sort_type: SortType::Hot as i16,
366 default_listing_type: ListingType::Subscribed as i16,
367 lang: "browser".into(),
369 send_notifications_to_email: false,
375 last_refreshed_at: None,
378 let inserted_user = User_::create(&conn, &new_user).unwrap();
380 let new_community = CommunityForm {
381 name: "test community_3".to_string(),
382 title: "nada".to_owned(),
385 creator_id: inserted_user.id,
394 last_refreshed_at: None,
400 let inserted_community = Community::create(&conn, &new_community).unwrap();
402 let new_post = PostForm {
403 name: "A test post".into(),
406 creator_id: inserted_user.id,
407 community_id: inserted_community.id,
415 embed_description: None,
423 let inserted_post = Post::create(&conn, &new_post).unwrap();
425 let expected_post = Post {
426 id: inserted_post.id,
427 name: "A test post".into(),
430 creator_id: inserted_user.id,
431 community_id: inserted_community.id,
432 published: inserted_post.published,
440 embed_description: None,
443 ap_id: inserted_post.ap_id.to_owned(),
448 let post_like_form = PostLikeForm {
449 post_id: inserted_post.id,
450 user_id: inserted_user.id,
454 let inserted_post_like = PostLike::like(&conn, &post_like_form).unwrap();
456 let expected_post_like = PostLike {
457 id: inserted_post_like.id,
458 post_id: inserted_post.id,
459 user_id: inserted_user.id,
460 published: inserted_post_like.published,
465 let post_saved_form = PostSavedForm {
466 post_id: inserted_post.id,
467 user_id: inserted_user.id,
470 let inserted_post_saved = PostSaved::save(&conn, &post_saved_form).unwrap();
472 let expected_post_saved = PostSaved {
473 id: inserted_post_saved.id,
474 post_id: inserted_post.id,
475 user_id: inserted_user.id,
476 published: inserted_post_saved.published,
480 let post_read_form = PostReadForm {
481 post_id: inserted_post.id,
482 user_id: inserted_user.id,
485 let inserted_post_read = PostRead::mark_as_read(&conn, &post_read_form).unwrap();
487 let expected_post_read = PostRead {
488 id: inserted_post_read.id,
489 post_id: inserted_post.id,
490 user_id: inserted_user.id,
491 published: inserted_post_read.published,
494 let read_post = Post::read(&conn, inserted_post.id).unwrap();
495 let updated_post = Post::update(&conn, inserted_post.id, &new_post).unwrap();
496 let like_removed = PostLike::remove(&conn, inserted_user.id, inserted_post.id).unwrap();
497 let saved_removed = PostSaved::unsave(&conn, &post_saved_form).unwrap();
498 let read_removed = PostRead::mark_as_unread(&conn, &post_read_form).unwrap();
499 let num_deleted = Post::delete(&conn, inserted_post.id).unwrap();
500 Community::delete(&conn, inserted_community.id).unwrap();
501 User_::delete(&conn, inserted_user.id).unwrap();
503 assert_eq!(expected_post, read_post);
504 assert_eq!(expected_post, inserted_post);
505 assert_eq!(expected_post, updated_post);
506 assert_eq!(expected_post_like, inserted_post_like);
507 assert_eq!(expected_post_saved, inserted_post_saved);
508 assert_eq!(expected_post_read, inserted_post_read);
509 assert_eq!(1, like_removed);
510 assert_eq!(1, saved_removed);
511 assert_eq!(1, read_removed);
512 assert_eq!(1, num_deleted);