4 // The faked schema since diesel doesn't do views
10 parent_id -> Nullable<Int4>,
14 published -> Timestamp,
15 updated -> Nullable<Timestamp>,
19 banned_from_community -> Bool,
20 creator_name -> Varchar,
21 creator_avatar -> Nullable<Text>,
25 user_id -> Nullable<Int4>,
26 my_vote -> Nullable<Int4>,
27 saved -> Nullable<Bool>,
36 parent_id -> Nullable<Int4>,
40 published -> Timestamp,
41 updated -> Nullable<Timestamp>,
45 banned_from_community -> Bool,
46 creator_name -> Varchar,
47 creator_avatar -> Nullable<Text>,
51 user_id -> Nullable<Int4>,
52 my_vote -> Nullable<Int4>,
53 saved -> Nullable<Bool>,
58 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
60 #[table_name = "comment_view"]
61 pub struct CommentView {
65 pub parent_id: Option<i32>,
69 pub published: chrono::NaiveDateTime,
70 pub updated: Option<chrono::NaiveDateTime>,
72 pub community_id: i32,
74 pub banned_from_community: bool,
75 pub creator_name: String,
76 pub creator_avatar: Option<String>,
80 pub user_id: Option<i32>,
81 pub my_vote: Option<i32>,
82 pub saved: Option<bool>,
85 pub struct CommentQueryBuilder<'a> {
86 conn: &'a PgConnection,
87 query: super::comment_view::comment_mview::BoxedQuery<'a, Pg>,
89 for_post_id: Option<i32>,
90 for_creator_id: Option<i32>,
91 search_term: Option<String>,
92 my_user_id: Option<i32>,
98 impl<'a> CommentQueryBuilder<'a> {
99 pub fn create(conn: &'a PgConnection) -> Self {
100 use super::comment_view::comment_mview::dsl::*;
102 let query = comment_mview.into_boxed();
104 CommentQueryBuilder {
107 sort: &SortType::New,
109 for_creator_id: None,
118 pub fn sort(mut self, sort: &'a SortType) -> Self {
123 pub fn for_post_id<T: MaybeOptional<i32>>(mut self, for_post_id: T) -> Self {
124 self.for_post_id = for_post_id.get_optional();
128 pub fn for_creator_id<T: MaybeOptional<i32>>(mut self, for_creator_id: T) -> Self {
129 self.for_creator_id = for_creator_id.get_optional();
133 pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
134 self.search_term = search_term.get_optional();
138 pub fn my_user_id<T: MaybeOptional<i32>>(mut self, my_user_id: T) -> Self {
139 self.my_user_id = my_user_id.get_optional();
143 pub fn saved_only(mut self, saved_only: bool) -> Self {
144 self.saved_only = saved_only;
148 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
149 self.page = page.get_optional();
153 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
154 self.limit = limit.get_optional();
158 pub fn list(self) -> Result<Vec<CommentView>, Error> {
159 use super::comment_view::comment_mview::dsl::*;
161 let mut query = self.query;
163 // The view lets you pass a null user_id, if you're not logged in
164 if let Some(my_user_id) = self.my_user_id {
165 query = query.filter(user_id.eq(my_user_id));
167 query = query.filter(user_id.is_null());
170 if let Some(for_creator_id) = self.for_creator_id {
171 query = query.filter(creator_id.eq(for_creator_id));
174 if let Some(for_post_id) = self.for_post_id {
175 query = query.filter(post_id.eq(for_post_id));
178 if let Some(search_term) = self.search_term {
179 query = query.filter(content.ilike(fuzzy_search(&search_term)));
183 query = query.filter(saved.eq(true));
186 query = match self.sort {
187 // SortType::Hot => query.order(hot_rank.desc(), published.desc()),
188 SortType::New => query.order_by(published.desc()),
189 SortType::TopAll => query.order_by(score.desc()),
190 SortType::TopYear => query
191 .filter(published.gt(now - 1.years()))
192 .order_by(score.desc()),
193 SortType::TopMonth => query
194 .filter(published.gt(now - 1.months()))
195 .order_by(score.desc()),
196 SortType::TopWeek => query
197 .filter(published.gt(now - 1.weeks()))
198 .order_by(score.desc()),
199 SortType::TopDay => query
200 .filter(published.gt(now - 1.days()))
201 .order_by(score.desc()),
202 _ => query.order_by(published.desc()),
205 let (limit, offset) = limit_and_offset(self.page, self.limit);
207 // Note: deleted and removed comments are done on the front side
211 .load::<CommentView>(self.conn)
218 from_comment_id: i32,
219 my_user_id: Option<i32>,
220 ) -> Result<Self, Error> {
221 use super::comment_view::comment_view::dsl::*;
223 let mut query = comment_view.into_boxed();
225 // The view lets you pass a null user_id, if you're not logged in
226 if let Some(my_user_id) = my_user_id {
227 query = query.filter(user_id.eq(my_user_id));
229 query = query.filter(user_id.is_null());
233 .filter(id.eq(from_comment_id))
234 .order_by(published.desc());
236 query.first::<Self>(conn)
240 // The faked schema since diesel doesn't do views
246 parent_id -> Nullable<Int4>,
250 published -> Timestamp,
251 updated -> Nullable<Timestamp>,
253 community_id -> Int4,
255 banned_from_community -> Bool,
256 creator_name -> Varchar,
257 creator_avatar -> Nullable<Text>,
261 user_id -> Nullable<Int4>,
262 my_vote -> Nullable<Int4>,
263 saved -> Nullable<Bool>,
264 recipient_id -> Int4,
269 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
271 #[table_name = "reply_view"]
272 pub struct ReplyView {
276 pub parent_id: Option<i32>,
280 pub published: chrono::NaiveDateTime,
281 pub updated: Option<chrono::NaiveDateTime>,
283 pub community_id: i32,
285 pub banned_from_community: bool,
286 pub creator_name: String,
287 pub creator_avatar: Option<String>,
291 pub user_id: Option<i32>,
292 pub my_vote: Option<i32>,
293 pub saved: Option<bool>,
294 pub recipient_id: i32,
297 pub struct ReplyQueryBuilder<'a> {
298 conn: &'a PgConnection,
299 query: super::comment_view::reply_view::BoxedQuery<'a, Pg>,
307 impl<'a> ReplyQueryBuilder<'a> {
308 pub fn create(conn: &'a PgConnection, for_user_id: i32) -> Self {
309 use super::comment_view::reply_view::dsl::*;
311 let query = reply_view.into_boxed();
317 sort: &SortType::New,
324 pub fn sort(mut self, sort: &'a SortType) -> Self {
329 pub fn unread_only(mut self, unread_only: bool) -> Self {
330 self.unread_only = unread_only;
334 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
335 self.page = page.get_optional();
339 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
340 self.limit = limit.get_optional();
344 pub fn list(self) -> Result<Vec<ReplyView>, Error> {
345 use super::comment_view::reply_view::dsl::*;
347 let mut query = self.query;
350 .filter(user_id.eq(self.for_user_id))
351 .filter(recipient_id.eq(self.for_user_id))
352 .filter(deleted.eq(false))
353 .filter(removed.eq(false));
355 if self.unread_only {
356 query = query.filter(read.eq(false));
359 query = match self.sort {
360 // SortType::Hot => query.order_by(hot_rank.desc()),
361 SortType::New => query.order_by(published.desc()),
362 SortType::TopAll => query.order_by(score.desc()),
363 SortType::TopYear => query
364 .filter(published.gt(now - 1.years()))
365 .order_by(score.desc()),
366 SortType::TopMonth => query
367 .filter(published.gt(now - 1.months()))
368 .order_by(score.desc()),
369 SortType::TopWeek => query
370 .filter(published.gt(now - 1.weeks()))
371 .order_by(score.desc()),
372 SortType::TopDay => query
373 .filter(published.gt(now - 1.days()))
374 .order_by(score.desc()),
375 _ => query.order_by(published.desc()),
378 let (limit, offset) = limit_and_offset(self.page, self.limit);
382 .load::<ReplyView>(self.conn)
388 use super::super::comment::*;
389 use super::super::community::*;
390 use super::super::post::*;
391 use super::super::user::*;
395 let conn = establish_unpooled_connection();
397 let new_user = UserForm {
398 name: "timmy".into(),
399 fedi_name: "rrf".into(),
400 preferred_username: None,
401 password_encrypted: "nope".into(),
403 matrix_user_id: None,
409 theme: "darkly".into(),
410 default_sort_type: SortType::Hot as i16,
411 default_listing_type: ListingType::Subscribed as i16,
412 lang: "browser".into(),
414 send_notifications_to_email: false,
417 let inserted_user = User_::create(&conn, &new_user).unwrap();
419 let new_community = CommunityForm {
420 name: "test community 5".to_string(),
421 title: "nada".to_owned(),
424 creator_id: inserted_user.id,
431 let inserted_community = Community::create(&conn, &new_community).unwrap();
433 let new_post = PostForm {
434 name: "A test post 2".into(),
435 creator_id: inserted_user.id,
438 community_id: inserted_community.id,
447 let inserted_post = Post::create(&conn, &new_post).unwrap();
449 let comment_form = CommentForm {
450 content: "A test comment 32".into(),
451 creator_id: inserted_user.id,
452 post_id: inserted_post.id,
460 let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
462 let comment_like_form = CommentLikeForm {
463 comment_id: inserted_comment.id,
464 post_id: inserted_post.id,
465 user_id: inserted_user.id,
469 let _inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
471 let expected_comment_view_no_user = CommentView {
472 id: inserted_comment.id,
473 content: "A test comment 32".into(),
474 creator_id: inserted_user.id,
475 post_id: inserted_post.id,
476 community_id: inserted_community.id,
482 banned_from_community: false,
483 published: inserted_comment.published,
485 creator_name: inserted_user.name.to_owned(),
486 creator_avatar: None,
495 let expected_comment_view_with_user = CommentView {
496 id: inserted_comment.id,
497 content: "A test comment 32".into(),
498 creator_id: inserted_user.id,
499 post_id: inserted_post.id,
500 community_id: inserted_community.id,
506 banned_from_community: false,
507 published: inserted_comment.published,
509 creator_name: inserted_user.name.to_owned(),
510 creator_avatar: None,
514 user_id: Some(inserted_user.id),
519 let read_comment_views_no_user = CommentQueryBuilder::create(&conn)
520 .for_post_id(inserted_post.id)
523 let read_comment_views_with_user = CommentQueryBuilder::create(&conn)
524 .for_post_id(inserted_post.id)
525 .my_user_id(inserted_user.id)
529 let like_removed = CommentLike::remove(&conn, &comment_like_form).unwrap();
530 let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();
531 Post::delete(&conn, inserted_post.id).unwrap();
532 Community::delete(&conn, inserted_community.id).unwrap();
533 User_::delete(&conn, inserted_user.id).unwrap();
535 assert_eq!(expected_comment_view_no_user, read_comment_views_no_user[0]);
537 expected_comment_view_with_user,
538 read_comment_views_with_user[0]
540 assert_eq!(1, num_deleted);
541 assert_eq!(1, like_removed);