From: Dessalines Date: Thu, 18 Feb 2021 15:38:25 +0000 (-0500) Subject: Adding a new comment sort for posts. Fixes #1294 (#1425) X-Git-Url: http://these/git/%22%7Burl%7D/%7B%60https:/%7Bpost.ap_id%7D?a=commitdiff_plain;h=0c4b57a6d0c8b0468060dd018887aecb3882730a;p=lemmy.git Adding a new comment sort for posts. Fixes #1294 (#1425) * Adding a new comment sort. Fixes #1294 * Fixing a migration comment. * Adding a comment for newest_comment_time_necro --- diff --git a/.rgignore b/.rgignore index d1b811b7..eab207b7 100644 --- a/.rgignore +++ b/.rgignore @@ -1 +1 @@ -*.sql +*.sqldump diff --git a/.rustfmt.toml b/.rustfmt.toml index f3efdc30..59528c80 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,5 +1,5 @@ tab_spaces = 2 edition="2018" imports_layout="HorizontalVertical" -merge_imports=true +imports_granularity="Crate" reorder_imports=true diff --git a/crates/db_queries/src/aggregates/post_aggregates.rs b/crates/db_queries/src/aggregates/post_aggregates.rs index 1d69fb40..ffee93be 100644 --- a/crates/db_queries/src/aggregates/post_aggregates.rs +++ b/crates/db_queries/src/aggregates/post_aggregates.rs @@ -13,6 +13,7 @@ pub struct PostAggregates { pub downvotes: i64, pub stickied: bool, pub published: chrono::NaiveDateTime, + pub newest_comment_time_necro: chrono::NaiveDateTime, // A newest comment time, limited to 2 days, to prevent necrobumping pub newest_comment_time: chrono::NaiveDateTime, } diff --git a/crates/db_queries/src/lib.rs b/crates/db_queries/src/lib.rs index ebe7394c..bf0de336 100644 --- a/crates/db_queries/src/lib.rs +++ b/crates/db_queries/src/lib.rs @@ -165,6 +165,7 @@ pub enum SortType { TopYear, TopAll, MostComments, + NewComments, } #[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone)] diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index e808d770..71232ebd 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -291,6 +291,7 @@ table! { downvotes -> Int8, stickied -> Bool, published -> Timestamp, + newest_comment_time_necro -> Timestamp, newest_comment_time -> Timestamp, } } diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index a262b7c1..b2a9902a 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -380,7 +380,9 @@ impl<'a> CommentQueryBuilder<'a> { SortType::Hot | SortType::Active => query .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc()) .then_order_by(comment_aggregates::published.desc()), - SortType::New | SortType::MostComments => query.order_by(comment::published.desc()), + SortType::New | SortType::MostComments | SortType::NewComments => { + query.order_by(comment::published.desc()) + } SortType::TopAll => query.order_by(comment_aggregates::score.desc()), SortType::TopYear => query .filter(comment::published.gt(now - 1.years())) diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 29e4c357..54e28de1 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -356,14 +356,19 @@ impl<'a> PostQueryBuilder<'a> { query = match self.sort { SortType::Active => query .then_order_by( - hot_rank(post_aggregates::score, post_aggregates::newest_comment_time).desc(), + hot_rank( + post_aggregates::score, + post_aggregates::newest_comment_time_necro, + ) + .desc(), ) - .then_order_by(post_aggregates::newest_comment_time.desc()), + .then_order_by(post_aggregates::newest_comment_time_necro.desc()), SortType::Hot => query .then_order_by(hot_rank(post_aggregates::score, post_aggregates::published).desc()) .then_order_by(post_aggregates::published.desc()), SortType::New => query.then_order_by(post_aggregates::published.desc()), SortType::MostComments => query.then_order_by(post_aggregates::comments.desc()), + SortType::NewComments => query.then_order_by(post_aggregates::newest_comment_time.desc()), SortType::TopAll => query.then_order_by(post_aggregates::score.desc()), SortType::TopYear => query .filter(post::published.gt(now - 1.years())) @@ -623,6 +628,7 @@ mod tests { downvotes: 0, stickied: false, published: agg.published, + newest_comment_time_necro: inserted_post.published, newest_comment_time: inserted_post.published, }, subscribed: false, diff --git a/crates/db_views_actor/src/user_mention_view.rs b/crates/db_views_actor/src/user_mention_view.rs index 811af6e7..ffdbe030 100644 --- a/crates/db_views_actor/src/user_mention_view.rs +++ b/crates/db_views_actor/src/user_mention_view.rs @@ -270,7 +270,9 @@ impl<'a> UserMentionQueryBuilder<'a> { SortType::Hot | SortType::Active => query .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc()) .then_order_by(comment_aggregates::published.desc()), - SortType::New | SortType::MostComments => query.order_by(comment::published.desc()), + SortType::New | SortType::MostComments | SortType::NewComments => { + query.order_by(comment::published.desc()) + } SortType::TopAll => query.order_by(comment_aggregates::score.desc()), SortType::TopYear => query .filter(comment::published.gt(now - 1.years())) diff --git a/crates/db_views_actor/src/user_view.rs b/crates/db_views_actor/src/user_view.rs index 2b85a63c..bbe889a2 100644 --- a/crates/db_views_actor/src/user_view.rs +++ b/crates/db_views_actor/src/user_view.rs @@ -110,7 +110,9 @@ impl<'a> UserQueryBuilder<'a> { SortType::Active => query .order_by(user_aggregates::comment_score.desc()) .then_order_by(user_::published.desc()), - SortType::New | SortType::MostComments => query.order_by(user_::published.desc()), + SortType::New | SortType::MostComments | SortType::NewComments => { + query.order_by(user_::published.desc()) + } SortType::TopAll => query.order_by(user_aggregates::comment_score.desc()), SortType::TopYear => query .filter(user_::published.gt(now - 1.years())) diff --git a/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql b/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql new file mode 100644 index 00000000..75f9aea3 --- /dev/null +++ b/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql @@ -0,0 +1,33 @@ +drop index idx_post_aggregates_newest_comment_time, +idx_post_aggregates_stickied_newest_comment_time, +idx_post_aggregates_stickied_comments; + +alter table post_aggregates drop column newest_comment_time; + +alter table post_aggregates rename column newest_comment_time_necro to newest_comment_time; + +create or replace function post_aggregates_comment_count() +returns trigger language plpgsql +as $$ +begin + IF (TG_OP = 'INSERT') THEN + update post_aggregates pa + set comments = comments + 1 + where pa.post_id = NEW.post_id; + + -- A 2 day necro-bump limit + update post_aggregates pa + set newest_comment_time = NEW.published + where pa.post_id = NEW.post_id + and published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + update post_aggregates pa + set comments = comments - 1 + from post p + where pa.post_id = p.id + and pa.post_id = OLD.post_id; + END IF; + return null; +end $$; + diff --git a/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql b/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql new file mode 100644 index 00000000..5452fbae --- /dev/null +++ b/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql @@ -0,0 +1,43 @@ +-- First rename current newest comment time to newest_comment_time_necro +-- necro means that time is limited to 2 days, whereas newest_comment_time ignores that. +alter table post_aggregates rename column newest_comment_time to newest_comment_time_necro; + +-- Add the newest_comment_time column +alter table post_aggregates add column newest_comment_time timestamp not null default now(); + +-- Set the current newest_comment_time based on the old ones +update post_aggregates set newest_comment_time = newest_comment_time_necro; + +-- Add the indexes for this new column +create index idx_post_aggregates_newest_comment_time on post_aggregates (newest_comment_time desc); +create index idx_post_aggregates_stickied_newest_comment_time on post_aggregates (stickied desc, newest_comment_time desc); + +-- Forgot to add index w/ stickied first for most comments: +create index idx_post_aggregates_stickied_comments on post_aggregates (stickied desc, comments desc); + +-- Alter the comment trigger to set the newest_comment_time, and newest_comment_time_necro +create or replace function post_aggregates_comment_count() +returns trigger language plpgsql +as $$ +begin + IF (TG_OP = 'INSERT') THEN + update post_aggregates pa + set comments = comments + 1, + newest_comment_time = NEW.published + where pa.post_id = NEW.post_id; + + -- A 2 day necro-bump limit + update post_aggregates pa + set newest_comment_time_necro = NEW.published + where pa.post_id = NEW.post_id + and published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + update post_aggregates pa + set comments = comments - 1 + from post p + where pa.post_id = p.id + and pa.post_id = OLD.post_id; + END IF; + return null; +end $$;