mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-12-30 02:09:44 -06:00
Shrink things that are rewritten in slow migrations (#5874)
* update schema.rs
* Require indexes for all foreign keys (#5872)
* add test
* add migration with missing indexes
* Fix foreign key indexes migration (#5875)
* Allow remote groups to follow Lemmy communities (fixes #5354) (#5864)
* Allow remote groups to follow Lemmy communities (fixes #5354)
* index
* rename columns
* review changes
* primary key
* Prevent stack overflow when fetching nested comment (#5787)
* attempt future wrapper
* Revert "attempt future wrapper"
This reverts commit ce95422228.
* use spawn
* remove `lazy` and change comment
* temporary change for test
* change 5000 back to 50
* fix comment about async laziness
* make columns nullable
* more shrinking
* update utils.sql
* update remove-aggregate-tables migration, and change indexed ranks back to non-null
* rename columns in remove-aggregate-tables migration, and fix later migrations
* remove comment
* optimize rank functions
* stuff
* more migration fixes
* other changes to migrations
* make schema setup tests pass
* stuff
* make tests pass
* crud trait is back
* add todo
* change immutable to stable
* use minutes for age
* clean up
* start cursor refactor
* finish cursor refactor
* remove "get_" prefix
* clean up
* import style consistency
* revert change to translations commit
* use i-love-jesus from crates.io
* remove some non_0_ and non_1_
* revert most changes in the crates folder
* fix column order in structs
* stuff
* fix migrations
* stuff (rust tests now pass)
* rename some vote-related fields
* fix some rust errors to make ts bindings generation work, and rename voteview field
* lint
* change stuff in api_tests to match changes to types
* change translations commit to prevent merge conflict
* rename "is_positive"
* remove like score range check test from post.spec.ts
* uncomment restrict-key thing
* prettier
* rerun ci
* add cfg_attr
* fix "A required parameter cannot follow an optional parameter"
* person_liked_combined: RENAME COLUMN liked_at TO voted_at
* for "newest comment" times: remove "after_published" prefix and don't convert to non-null
* move "voted_at" rename to "rename_timestamp_add_at" migration
* remove added uses of as_select
* fix sql code referencing "liked_at"
* clippy
* restore as_select uses that were already present
* change lemmy-js-client version
---------
Co-authored-by: Nutomic <me@nutomic.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Dessalines <tyhou13@gmx.com>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
"eslint-plugin-prettier": "^5.5.0",
|
||||
"jest": "^30.0.0",
|
||||
"joi": "^17.13.3",
|
||||
"lemmy-js-client": "1.0.0-enum-variants-snake-case.3",
|
||||
"lemmy-js-client": "1.0.0-bool-vote.2",
|
||||
"prettier": "^3.5.3",
|
||||
"ts-jest": "^29.4.0",
|
||||
"tsoa": "^6.6.0",
|
||||
|
||||
10
api_tests/pnpm-lock.yaml
generated
10
api_tests/pnpm-lock.yaml
generated
@@ -36,8 +36,8 @@ importers:
|
||||
specifier: ^17.13.3
|
||||
version: 17.13.3
|
||||
lemmy-js-client:
|
||||
specifier: 1.0.0-enum-variants-snake-case.3
|
||||
version: 1.0.0-enum-variants-snake-case.3
|
||||
specifier: 1.0.0-bool-vote.2
|
||||
version: 1.0.0-bool-vote.2
|
||||
prettier:
|
||||
specifier: ^3.5.3
|
||||
version: 3.6.2
|
||||
@@ -1656,8 +1656,8 @@ packages:
|
||||
keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
|
||||
lemmy-js-client@1.0.0-enum-variants-snake-case.3:
|
||||
resolution: {integrity: sha512-IFdDO9KZ7JKfuVJVpb9xqCVZEmZZVnAATFxDiG94RMp0dPAu8wOyD9OcT/nVn7sXmjbuex+3BFwjC2M6TlWj9A==}
|
||||
lemmy-js-client@1.0.0-bool-vote.2:
|
||||
resolution: {integrity: sha512-RqePoajuK7WNv63W6FzH4cf+Q5ahNCo6kxriFLS21BsJok9olap4AitgyN6p+swLVFkjIeSj11dCT1Bf8wqt3Q==}
|
||||
|
||||
leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
@@ -4399,7 +4399,7 @@ snapshots:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
|
||||
lemmy-js-client@1.0.0-enum-variants-snake-case.3:
|
||||
lemmy-js-client@1.0.0-bool-vote.2:
|
||||
dependencies:
|
||||
'@tsoa/runtime': 6.6.0
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -292,7 +292,11 @@ test("Unlike a comment", async () => {
|
||||
expect(gammaComment1?.creator.local).toBe(false);
|
||||
expect(gammaComment1?.comment.score).toBe(1);
|
||||
|
||||
let unlike = await likeComment(alpha, 0, commentRes.comment_view.comment);
|
||||
let unlike = await likeComment(
|
||||
alpha,
|
||||
undefined,
|
||||
commentRes.comment_view.comment,
|
||||
);
|
||||
expect(unlike.comment_view.comment.score).toBe(0);
|
||||
|
||||
// Make sure that comment is unliked on beta
|
||||
@@ -330,7 +334,7 @@ test("Federated comment like", async () => {
|
||||
throw "Missing beta comment";
|
||||
}
|
||||
|
||||
let like = await likeComment(beta, 1, betaComment.comment);
|
||||
let like = await likeComment(beta, true, betaComment.comment);
|
||||
expect(like.comment_view.comment.score).toBe(2);
|
||||
|
||||
// Get the post from alpha, check the likes
|
||||
|
||||
@@ -169,11 +169,11 @@ test("Unlike a post", async () => {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
let postRes = await createPost(alpha, betaCommunity.community.id);
|
||||
let unlike = await likePost(alpha, 0, postRes.post_view.post);
|
||||
let unlike = await likePost(alpha, undefined, postRes.post_view.post);
|
||||
expect(unlike.post_view.post.score).toBe(0);
|
||||
|
||||
// Try to unlike it again, make sure it stays at 0
|
||||
let unlike2 = await likePost(alpha, 0, postRes.post_view.post);
|
||||
let unlike2 = await likePost(alpha, undefined, postRes.post_view.post);
|
||||
expect(unlike2.post_view.post.score).toBe(0);
|
||||
|
||||
// Make sure that post is unliked on beta
|
||||
@@ -190,40 +190,6 @@ test("Unlike a post", async () => {
|
||||
await assertPostFederation(betaPost, postRes.post_view);
|
||||
});
|
||||
|
||||
test("Make sure like is within range", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
let postRes = await createPost(alpha, betaCommunity.community.id);
|
||||
|
||||
// Try a like with score 2
|
||||
await expect(
|
||||
likePost(alpha, 2, postRes.post_view.post),
|
||||
).rejects.toStrictEqual(
|
||||
new LemmyError("couldnt_like_post", statusBadRequest),
|
||||
);
|
||||
|
||||
// Try a like with score -2
|
||||
await expect(
|
||||
likePost(alpha, -2, postRes.post_view.post),
|
||||
).rejects.toStrictEqual(
|
||||
new LemmyError("couldnt_like_post", statusBadRequest),
|
||||
);
|
||||
|
||||
// Make sure that post stayed at 1
|
||||
const betaPost = await waitForPost(
|
||||
beta,
|
||||
postRes.post_view.post,
|
||||
post => post?.post.score === 1,
|
||||
);
|
||||
|
||||
expect(betaPost).toBeDefined();
|
||||
expect(betaPost?.community.local).toBe(true);
|
||||
expect(betaPost?.creator.local).toBe(false);
|
||||
expect(betaPost?.post.score).toBe(1);
|
||||
await assertPostFederation(betaPost, postRes.post_view);
|
||||
});
|
||||
|
||||
test("Update a post", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
|
||||
@@ -164,8 +164,8 @@ test("Only followers can view and interact with private community content", asyn
|
||||
|
||||
const post1 = await createPost(user, betaCommunity!.id);
|
||||
expect(post1.post_view).toBeDefined();
|
||||
const like = await likeComment(user, 1, resolvedComment!.comment);
|
||||
expect(like.comment_view.comment_actions?.like_score).toBe(1);
|
||||
const like = await likeComment(user, true, resolvedComment!.comment);
|
||||
expect(like.comment_view.comment_actions?.vote_is_upvote).toBe(true);
|
||||
});
|
||||
|
||||
test("Reject follower", async () => {
|
||||
|
||||
@@ -524,12 +524,12 @@ export async function followCommunity(
|
||||
|
||||
export async function likePost(
|
||||
api: LemmyHttp,
|
||||
score: number,
|
||||
is_upvote: boolean | undefined,
|
||||
post: Post,
|
||||
): Promise<PostResponse> {
|
||||
let form: CreatePostLike = {
|
||||
post_id: post.id,
|
||||
score: score,
|
||||
is_upvote: is_upvote,
|
||||
};
|
||||
|
||||
return api.likePost(form);
|
||||
@@ -588,12 +588,12 @@ export async function removeComment(
|
||||
|
||||
export async function likeComment(
|
||||
api: LemmyHttp,
|
||||
score: number,
|
||||
is_upvote: boolean | undefined,
|
||||
comment: Comment,
|
||||
): Promise<CommentResponse> {
|
||||
let form: CreateCommentLike = {
|
||||
comment_id: comment.id,
|
||||
score,
|
||||
is_upvote,
|
||||
};
|
||||
return api.likeComment(form);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ pub async fn like_comment(
|
||||
let my_person_id = local_user_view.person.id;
|
||||
|
||||
check_local_vote_mode(
|
||||
data.score,
|
||||
data.is_upvote,
|
||||
PostOrCommentId::Comment(comment_id),
|
||||
&local_site,
|
||||
my_person_id,
|
||||
@@ -57,7 +57,7 @@ pub async fn like_comment(
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
let previous_score = orig_comment.comment_actions.and_then(|p| p.like_score);
|
||||
let previous_is_upvote = orig_comment.comment_actions.and_then(|p| p.vote_is_upvote);
|
||||
|
||||
check_community_user_action(
|
||||
&local_user_view,
|
||||
@@ -66,30 +66,29 @@ pub async fn like_comment(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut like_form = CommentLikeForm::new(my_person_id, data.comment_id, data.score);
|
||||
|
||||
// Remove any likes first
|
||||
CommentActions::remove_like(&mut context.pool(), my_person_id, comment_id).await?;
|
||||
if let Some(previous_score) = previous_score {
|
||||
if let Some(previous_is_upvote) = previous_is_upvote {
|
||||
PersonActions::remove_like(
|
||||
&mut context.pool(),
|
||||
my_person_id,
|
||||
orig_comment.creator.id,
|
||||
previous_score,
|
||||
previous_is_upvote,
|
||||
)
|
||||
.await
|
||||
// Ignore errors, since a previous_like of zero throws an error
|
||||
.ok();
|
||||
}
|
||||
|
||||
if like_form.like_score != 0 {
|
||||
if let Some(is_upvote) = data.is_upvote {
|
||||
let mut like_form = CommentLikeForm::new(my_person_id, data.comment_id, is_upvote);
|
||||
like_form = plugin_hook_before("before_comment_vote", like_form).await?;
|
||||
let like = CommentActions::like(&mut context.pool(), &like_form).await?;
|
||||
PersonActions::like(
|
||||
&mut context.pool(),
|
||||
my_person_id,
|
||||
orig_comment.creator.id,
|
||||
like_form.like_score,
|
||||
like_form.vote_is_upvote,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -101,8 +100,8 @@ pub async fn like_comment(
|
||||
object_id: orig_comment.comment.ap_id,
|
||||
actor: local_user_view.person.clone(),
|
||||
community: orig_comment.community,
|
||||
previous_score,
|
||||
new_score: data.score,
|
||||
previous_is_upvote,
|
||||
new_is_upvote: data.is_upvote,
|
||||
},
|
||||
&context,
|
||||
)?;
|
||||
|
||||
@@ -41,7 +41,7 @@ pub async fn like_post(
|
||||
let my_person_id = local_user_view.person.id;
|
||||
|
||||
check_local_vote_mode(
|
||||
data.score,
|
||||
data.is_upvote,
|
||||
PostOrCommentId::Post(post_id),
|
||||
&local_site,
|
||||
my_person_id,
|
||||
@@ -59,34 +59,33 @@ pub async fn like_post(
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
let previous_score = orig_post.post_actions.and_then(|p| p.like_score);
|
||||
let previous_is_upvote = orig_post.post_actions.and_then(|p| p.vote_is_upvote);
|
||||
|
||||
check_community_user_action(&local_user_view, &orig_post.community, &mut context.pool()).await?;
|
||||
|
||||
let mut like_form = PostLikeForm::new(data.post_id, my_person_id, data.score);
|
||||
|
||||
// Remove any likes first
|
||||
PostActions::remove_like(&mut context.pool(), my_person_id, post_id).await?;
|
||||
if let Some(previous_score) = previous_score {
|
||||
if let Some(previous_is_upvote) = previous_is_upvote {
|
||||
PersonActions::remove_like(
|
||||
&mut context.pool(),
|
||||
my_person_id,
|
||||
orig_post.creator.id,
|
||||
previous_score,
|
||||
previous_is_upvote,
|
||||
)
|
||||
.await
|
||||
// Ignore errors, since a previous_like of zero throws an error
|
||||
.ok();
|
||||
}
|
||||
|
||||
if like_form.like_score != 0 {
|
||||
if let Some(is_upvote) = data.is_upvote {
|
||||
let mut like_form = PostLikeForm::new(data.post_id, my_person_id, is_upvote);
|
||||
like_form = plugin_hook_before("before_post_vote", like_form).await?;
|
||||
let like = PostActions::like(&mut context.pool(), &like_form).await?;
|
||||
PersonActions::like(
|
||||
&mut context.pool(),
|
||||
my_person_id,
|
||||
orig_post.creator.id,
|
||||
like_form.like_score,
|
||||
like_form.vote_is_upvote,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -102,8 +101,8 @@ pub async fn like_post(
|
||||
object_id: orig_post.post.ap_id,
|
||||
actor: local_user_view.person.clone(),
|
||||
community: orig_post.community.clone(),
|
||||
previous_score,
|
||||
new_score: data.score,
|
||||
previous_is_upvote,
|
||||
new_is_upvote: data.is_upvote,
|
||||
},
|
||||
&context,
|
||||
)?;
|
||||
|
||||
@@ -138,7 +138,7 @@ mod tests {
|
||||
let post_form_1 = PostInsertForm::new("A test post tubular".into(), sara.id, community.id);
|
||||
let post_1 = Post::create(pool, &post_form_1).await?;
|
||||
|
||||
let post_like_form_1 = PostLikeForm::new(post_1.id, sara.id, 1);
|
||||
let post_like_form_1 = PostLikeForm::new(post_1.id, sara.id, true);
|
||||
let _post_like_1 = PostActions::like(pool, &post_like_form_1).await?;
|
||||
|
||||
let post_form_2 = PostInsertForm::new("A test post radical".into(), sara.id, community.id);
|
||||
@@ -148,7 +148,7 @@ mod tests {
|
||||
CommentInsertForm::new(sara.id, post_1.id, "A test comment tubular".into());
|
||||
let comment_1 = Comment::create(pool, &comment_form_1, None).await?;
|
||||
|
||||
let comment_like_form_1 = CommentLikeForm::new(sara.id, comment_1.id, 1);
|
||||
let comment_like_form_1 = CommentLikeForm::new(sara.id, comment_1.id, true);
|
||||
let _comment_like_1 = CommentActions::like(pool, &comment_like_form_1).await?;
|
||||
|
||||
let comment_form_2 =
|
||||
@@ -160,8 +160,8 @@ mod tests {
|
||||
PostView::read(pool, post_1.id, Some(&sara_local_user), instance.id, false).await?;
|
||||
assert_eq!(1, post_view_1.post.score);
|
||||
assert_eq!(
|
||||
Some(1),
|
||||
post_view_1.post_actions.and_then(|pa| pa.like_score)
|
||||
Some(true),
|
||||
post_view_1.post_actions.and_then(|pa| pa.vote_is_upvote)
|
||||
);
|
||||
|
||||
// Read saras comment to make sure it has a like
|
||||
@@ -169,8 +169,10 @@ mod tests {
|
||||
CommentView::read(pool, comment_1.id, Some(&sara_local_user), instance.id).await?;
|
||||
assert_eq!(1, comment_view_1.post.score);
|
||||
assert_eq!(
|
||||
Some(1),
|
||||
comment_view_1.comment_actions.and_then(|ca| ca.like_score)
|
||||
Some(true),
|
||||
comment_view_1
|
||||
.comment_actions
|
||||
.and_then(|ca| ca.vote_is_upvote)
|
||||
);
|
||||
|
||||
// Remove the user data
|
||||
@@ -232,7 +234,10 @@ mod tests {
|
||||
let post_view_1 =
|
||||
PostView::read(pool, post_1.id, Some(&sara_local_user), instance.id, false).await?;
|
||||
assert_eq!(0, post_view_1.post.score);
|
||||
assert_eq!(None, post_view_1.post_actions.and_then(|pa| pa.like_score));
|
||||
assert_eq!(
|
||||
None,
|
||||
post_view_1.post_actions.and_then(|pa| pa.vote_is_upvote)
|
||||
);
|
||||
|
||||
// comment
|
||||
let comment_view_1 =
|
||||
@@ -240,7 +245,9 @@ mod tests {
|
||||
assert_eq!(0, comment_view_1.post.score);
|
||||
assert_eq!(
|
||||
None,
|
||||
comment_view_1.comment_actions.and_then(|ca| ca.like_score)
|
||||
comment_view_1
|
||||
.comment_actions
|
||||
.and_then(|ca| ca.vote_is_upvote)
|
||||
);
|
||||
|
||||
// Now restore the content, and make sure it got appended
|
||||
|
||||
@@ -125,7 +125,7 @@ pub async fn create_comment(
|
||||
.send(&context);
|
||||
|
||||
// You like your own comment by default
|
||||
let like_form = CommentLikeForm::new(local_user_view.person.id, inserted_comment.id, 1);
|
||||
let like_form = CommentLikeForm::new(local_user_view.person.id, inserted_comment.id, true);
|
||||
|
||||
CommentActions::like(&mut context.pool(), &like_form).await?;
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ pub async fn create_post(
|
||||
// They like their own post by default
|
||||
let person_id = local_user_view.person.id;
|
||||
let post_id = inserted_post.id;
|
||||
let like_form = PostLikeForm::new(post_id, person_id, 1);
|
||||
let like_form = PostLikeForm::new(post_id, person_id, true);
|
||||
|
||||
PostActions::like(&mut context.pool(), &like_form).await?;
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ pub enum SendActivityData {
|
||||
object_id: DbUrl,
|
||||
actor: Person,
|
||||
community: Community,
|
||||
previous_score: Option<i16>,
|
||||
new_score: i16,
|
||||
previous_is_upvote: Option<bool>,
|
||||
new_is_upvote: Option<bool>,
|
||||
},
|
||||
FollowCommunity(Community, Person, bool),
|
||||
FollowMultiCommunity(MultiCommunity, Person, bool),
|
||||
|
||||
@@ -311,7 +311,7 @@ pub fn check_comment_deleted_or_removed(comment: &Comment) -> LemmyResult<()> {
|
||||
}
|
||||
|
||||
pub async fn check_local_vote_mode(
|
||||
score: i16,
|
||||
is_upvote: Option<bool>,
|
||||
post_or_comment_id: PostOrCommentId,
|
||||
local_site: &LocalSite,
|
||||
person_id: PersonId,
|
||||
@@ -322,8 +322,8 @@ pub async fn check_local_vote_mode(
|
||||
PostOrCommentId::Comment(_) => (local_site.comment_downvotes, local_site.comment_upvotes),
|
||||
};
|
||||
|
||||
let downvote_fail = score == -1 && downvote_setting == FederationMode::Disable;
|
||||
let upvote_fail = score == 1 && upvote_setting == FederationMode::Disable;
|
||||
let downvote_fail = is_upvote == Some(false) && downvote_setting == FederationMode::Disable;
|
||||
let upvote_fail = is_upvote == Some(true) && upvote_setting == FederationMode::Disable;
|
||||
|
||||
// Undo previous vote for item if new vote fails
|
||||
if downvote_fail || upvote_fail {
|
||||
|
||||
@@ -144,7 +144,7 @@ impl Activity for CreateOrUpdateNote {
|
||||
let comment = ApubComment::from_json(self.object, context).await?;
|
||||
|
||||
// author likes their own comment by default
|
||||
let like_form = CommentLikeForm::new(comment.creator_id, comment.id, 1);
|
||||
let like_form = CommentLikeForm::new(comment.creator_id, comment.id, true);
|
||||
CommentActions::like(&mut context.pool(), &like_form).await?;
|
||||
|
||||
// Calculate initial hot_rank
|
||||
|
||||
@@ -144,7 +144,7 @@ impl Activity for CreateOrUpdatePage {
|
||||
let post = ApubPost::from_json(self.object, context).await?;
|
||||
|
||||
// author likes their own post by default
|
||||
let like_form = PostLikeForm::new(post.id, post.creator_id, 1);
|
||||
let like_form = PostLikeForm::new(post.id, post.creator_id, true);
|
||||
PostActions::like(&mut context.pool(), &like_form).await?;
|
||||
|
||||
// Calculate initial hot_rank for post
|
||||
|
||||
@@ -253,15 +253,15 @@ pub async fn match_outgoing_activities(
|
||||
object_id,
|
||||
actor,
|
||||
community,
|
||||
previous_score,
|
||||
new_score,
|
||||
previous_is_upvote,
|
||||
new_is_upvote,
|
||||
} => {
|
||||
send_like_activity(
|
||||
object_id,
|
||||
actor,
|
||||
community,
|
||||
previous_score,
|
||||
new_score,
|
||||
previous_is_upvote,
|
||||
new_is_upvote,
|
||||
context,
|
||||
)
|
||||
.await
|
||||
|
||||
@@ -5,7 +5,7 @@ use lemmy_apub_objects::{
|
||||
objects::{community::ApubCommunity, person::ApubPerson, PostOrComment},
|
||||
utils::protocol::InCommunity,
|
||||
};
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult, UntranslatedError};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::Display;
|
||||
use url::Url;
|
||||
@@ -26,24 +26,19 @@ pub enum VoteType {
|
||||
Dislike,
|
||||
}
|
||||
|
||||
impl TryFrom<i16> for VoteType {
|
||||
type Error = LemmyError;
|
||||
|
||||
fn try_from(value: i16) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
1 => Ok(VoteType::Like),
|
||||
-1 => Ok(VoteType::Dislike),
|
||||
_ => Err(UntranslatedError::InvalidVoteValue.into()),
|
||||
impl From<bool> for VoteType {
|
||||
fn from(value: bool) -> Self {
|
||||
if value {
|
||||
VoteType::Like
|
||||
} else {
|
||||
VoteType::Dislike
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&VoteType> for i16 {
|
||||
fn from(value: &VoteType) -> i16 {
|
||||
match value {
|
||||
VoteType::Like => 1,
|
||||
VoteType::Dislike => -1,
|
||||
}
|
||||
impl From<&VoteType> for bool {
|
||||
fn from(value: &VoteType) -> Self {
|
||||
value == &VoteType::Like
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ pub(crate) async fn send_like_activity(
|
||||
object_id: DbUrl,
|
||||
actor: Person,
|
||||
community: Community,
|
||||
previous_score: Option<i16>,
|
||||
new_score: i16,
|
||||
previous_is_upvote: Option<bool>,
|
||||
new_is_upvote: Option<bool>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<()> {
|
||||
let object_id: ObjectId<PostOrComment> = object_id.into();
|
||||
@@ -47,13 +47,13 @@ pub(crate) async fn send_like_activity(
|
||||
let community: ApubCommunity = community.into();
|
||||
|
||||
let empty = ActivitySendTargets::empty();
|
||||
// score of 1 means upvote, -1 downvote, 0 undo a previous vote
|
||||
if new_score != 0 {
|
||||
let vote = Vote::new(object_id, &actor, new_score.try_into()?, &context)?;
|
||||
if let Some(s) = new_is_upvote {
|
||||
let vote = Vote::new(object_id, &actor, s.into(), &context)?;
|
||||
let activity = AnnouncableActivities::Vote(vote);
|
||||
send_activity_in_community(activity, &actor, &community, empty, false, &context).await
|
||||
} else {
|
||||
let previous_vote_type = if previous_score.unwrap_or_default() > 0 {
|
||||
// undo a previous vote
|
||||
let previous_vote_type = if previous_is_upvote == Some(true) {
|
||||
VoteType::Like
|
||||
} else {
|
||||
VoteType::Dislike
|
||||
|
||||
@@ -13,7 +13,6 @@ use crate::{
|
||||
utils::{
|
||||
functions::{coalesce, hot_rank},
|
||||
get_conn,
|
||||
validate_like,
|
||||
DbPool,
|
||||
DELETED_REPLACEMENT_TEXT,
|
||||
},
|
||||
@@ -32,7 +31,7 @@ use diesel_ltree::{dsl::LtreeExtensions, Ltree};
|
||||
use diesel_uplete::{uplete, UpleteCount};
|
||||
use lemmy_db_schema_file::schema::{comment, comment_actions, community, post};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
||||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||
settings::structs::Settings,
|
||||
};
|
||||
use url::Url;
|
||||
@@ -316,8 +315,6 @@ impl Likeable for CommentActions {
|
||||
async fn like(pool: &mut DbPool<'_>, form: &Self::Form) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
validate_like(form.like_score).with_lemmy_type(LemmyErrorType::CouldntCreate)?;
|
||||
|
||||
insert_into(comment_actions::table)
|
||||
.values(form)
|
||||
.on_conflict((comment_actions::comment_id, comment_actions::person_id))
|
||||
@@ -335,8 +332,8 @@ impl Likeable for CommentActions {
|
||||
) -> LemmyResult<UpleteCount> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
uplete(comment_actions::table.find((person_id, comment_id)))
|
||||
.set_null(comment_actions::like_score)
|
||||
.set_null(comment_actions::liked_at)
|
||||
.set_null(comment_actions::vote_is_upvote)
|
||||
.set_null(comment_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntCreate)
|
||||
@@ -349,8 +346,8 @@ impl Likeable for CommentActions {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
uplete(comment_actions::table.filter(comment_actions::person_id.eq(creator_id)))
|
||||
.set_null(comment_actions::like_score)
|
||||
.set_null(comment_actions::liked_at)
|
||||
.set_null(comment_actions::vote_is_upvote)
|
||||
.set_null(comment_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdate)
|
||||
@@ -367,8 +364,8 @@ impl Likeable for CommentActions {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
uplete(comment_actions::table.filter(comment_actions::comment_id.eq_any(comment_ids.clone())))
|
||||
.set_null(comment_actions::like_score)
|
||||
.set_null(comment_actions::liked_at)
|
||||
.set_null(comment_actions::vote_is_upvote)
|
||||
.set_null(comment_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdate)
|
||||
@@ -509,10 +506,10 @@ mod tests {
|
||||
Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)).await?;
|
||||
|
||||
// Comment Like
|
||||
let comment_like_form = CommentLikeForm::new(inserted_person.id, inserted_comment.id, 1);
|
||||
let comment_like_form = CommentLikeForm::new(inserted_person.id, inserted_comment.id, true);
|
||||
|
||||
let inserted_comment_like = CommentActions::like(pool, &comment_like_form).await?;
|
||||
assert_eq!(Some(1), inserted_comment_like.like_score);
|
||||
assert_eq!(Some(true), inserted_comment_like.vote_is_upvote);
|
||||
|
||||
// Comment Saved
|
||||
let comment_saved_form = CommentSavedForm::new(inserted_person.id, inserted_comment.id);
|
||||
@@ -596,7 +593,7 @@ mod tests {
|
||||
let _inserted_child_comment =
|
||||
Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)).await?;
|
||||
|
||||
let comment_like = CommentLikeForm::new(inserted_person.id, inserted_comment.id, 1);
|
||||
let comment_like = CommentLikeForm::new(inserted_person.id, inserted_comment.id, true);
|
||||
|
||||
CommentActions::like(pool, &comment_like).await?;
|
||||
|
||||
@@ -607,7 +604,8 @@ mod tests {
|
||||
assert_eq!(0, comment_aggs_before_delete.downvotes);
|
||||
|
||||
// Add a post dislike from the other person
|
||||
let comment_dislike = CommentLikeForm::new(another_inserted_person.id, inserted_comment.id, -1);
|
||||
let comment_dislike =
|
||||
CommentLikeForm::new(another_inserted_person.id, inserted_comment.id, false);
|
||||
|
||||
CommentActions::like(pool, &comment_dislike).await?;
|
||||
|
||||
|
||||
@@ -365,15 +365,11 @@ impl PersonActions {
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
target_id: PersonId,
|
||||
like_score: i16,
|
||||
vote_is_upvote: bool,
|
||||
) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let (upvotes_inc, downvotes_inc) = match like_score {
|
||||
1 => (1, 0),
|
||||
-1 => (0, 1),
|
||||
_ => return Err(LemmyErrorType::NotFound.into()),
|
||||
};
|
||||
let (upvotes_inc, downvotes_inc) = if vote_is_upvote { (1, 0) } else { (0, 1) };
|
||||
|
||||
let voted_at = Utc::now();
|
||||
|
||||
@@ -400,20 +396,16 @@ impl PersonActions {
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
|
||||
/// Removes a person like. A previous_score of zero throws an error.
|
||||
/// Removes a person like.
|
||||
pub async fn remove_like(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
target_id: PersonId,
|
||||
previous_score: i16,
|
||||
previous_is_upvote: bool,
|
||||
) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let (upvotes_inc, downvotes_inc) = match previous_score {
|
||||
1 => (-1, 0),
|
||||
-1 => (0, -1),
|
||||
_ => return Err(LemmyErrorType::NotFound.into()),
|
||||
};
|
||||
let (upvotes_inc, downvotes_inc) = if previous_is_upvote { (-1, 0) } else { (0, -1) };
|
||||
let voted_at = Utc::now();
|
||||
|
||||
insert_into(person_actions::table)
|
||||
@@ -575,7 +567,7 @@ mod tests {
|
||||
);
|
||||
let inserted_post = Post::create(pool, &new_post).await?;
|
||||
|
||||
let post_like = PostLikeForm::new(inserted_post.id, inserted_person.id, 1);
|
||||
let post_like = PostLikeForm::new(inserted_post.id, inserted_person.id, true);
|
||||
let _inserted_post_like = PostActions::like(pool, &post_like).await?;
|
||||
|
||||
let comment_form = CommentInsertForm::new(
|
||||
@@ -585,7 +577,7 @@ mod tests {
|
||||
);
|
||||
let inserted_comment = Comment::create(pool, &comment_form, None).await?;
|
||||
|
||||
let mut comment_like = CommentLikeForm::new(inserted_person.id, inserted_comment.id, 1);
|
||||
let mut comment_like = CommentLikeForm::new(inserted_person.id, inserted_comment.id, true);
|
||||
|
||||
let _inserted_comment_like = CommentActions::like(pool, &comment_like).await?;
|
||||
|
||||
@@ -598,7 +590,7 @@ mod tests {
|
||||
Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)).await?;
|
||||
|
||||
let child_comment_like =
|
||||
CommentLikeForm::new(another_inserted_person.id, inserted_child_comment.id, 1);
|
||||
CommentLikeForm::new(another_inserted_person.id, inserted_child_comment.id, true);
|
||||
|
||||
let _inserted_child_comment_like = CommentActions::like(pool, &child_comment_like).await?;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ use crate::{
|
||||
functions::{coalesce, hot_rank, scaled_rank},
|
||||
get_conn,
|
||||
now,
|
||||
validate_like,
|
||||
DbPool,
|
||||
DELETED_REPLACEMENT_TEXT,
|
||||
FETCH_LIMIT_MAX,
|
||||
@@ -43,7 +42,7 @@ use lemmy_db_schema_file::{
|
||||
schema::{community, local_user, person, post, post_actions},
|
||||
};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
||||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||
settings::structs::Settings,
|
||||
};
|
||||
use url::Url;
|
||||
@@ -313,7 +312,10 @@ impl Post {
|
||||
diesel::update(post::table.find(post_id))
|
||||
.set((
|
||||
post::hot_rank.eq(hot_rank(post::score, post::published_at)),
|
||||
post::hot_rank_active.eq(hot_rank(post::score, post::newest_comment_time_necro_at)),
|
||||
post::hot_rank_active.eq(hot_rank(
|
||||
post::score,
|
||||
coalesce(post::newest_comment_time_necro_at, post::published_at),
|
||||
)),
|
||||
post::scaled_rank.eq(scaled_rank(
|
||||
post::score,
|
||||
post::published_at,
|
||||
@@ -349,8 +351,6 @@ impl Likeable for PostActions {
|
||||
async fn like(pool: &mut DbPool<'_>, form: &Self::Form) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
validate_like(form.like_score).with_lemmy_type(LemmyErrorType::CouldntCreate)?;
|
||||
|
||||
insert_into(post_actions::table)
|
||||
.values(form)
|
||||
.on_conflict((post_actions::post_id, post_actions::person_id))
|
||||
@@ -369,8 +369,8 @@ impl Likeable for PostActions {
|
||||
) -> LemmyResult<UpleteCount> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
uplete(post_actions::table.find((person_id, post_id)))
|
||||
.set_null(post_actions::like_score)
|
||||
.set_null(post_actions::liked_at)
|
||||
.set_null(post_actions::vote_is_upvote)
|
||||
.set_null(post_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdate)
|
||||
@@ -383,8 +383,8 @@ impl Likeable for PostActions {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
uplete(post_actions::table.filter(post_actions::person_id.eq(person_id)))
|
||||
.set_null(post_actions::like_score)
|
||||
.set_null(post_actions::liked_at)
|
||||
.set_null(post_actions::vote_is_upvote)
|
||||
.set_null(post_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdate)
|
||||
@@ -400,8 +400,8 @@ impl Likeable for PostActions {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
uplete(post_actions::table.filter(post_actions::post_id.eq_any(post_ids.clone())))
|
||||
.set_null(post_actions::like_score)
|
||||
.set_null(post_actions::liked_at)
|
||||
.set_null(post_actions::vote_is_upvote)
|
||||
.set_null(post_actions::voted_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdate)
|
||||
@@ -533,7 +533,10 @@ impl PostActions {
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
|
||||
pub async fn from_cursor(cursor: &PaginationCursor, pool: &mut DbPool<'_>) -> LemmyResult<Self> {
|
||||
pub async fn from_cursor(
|
||||
cursor: &PaginationCursor,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<PostActions> {
|
||||
let [(_, person_id), (_, post_id)] = cursor.prefixes_and_ids()?;
|
||||
Self::read(pool, PostId(post_id), PersonId(person_id)).await
|
||||
}
|
||||
@@ -688,8 +691,8 @@ mod tests {
|
||||
score: 1,
|
||||
hot_rank: RANK_DEFAULT,
|
||||
hot_rank_active: RANK_DEFAULT,
|
||||
newest_comment_time_at: inserted_post.published_at,
|
||||
newest_comment_time_necro_at: inserted_post.published_at,
|
||||
newest_comment_time_at: None,
|
||||
newest_comment_time_necro_at: None,
|
||||
report_count: 0,
|
||||
scaled_rank: RANK_DEFAULT,
|
||||
unresolved_report_count: 0,
|
||||
@@ -697,10 +700,10 @@ mod tests {
|
||||
};
|
||||
|
||||
// Post Like
|
||||
let post_like_form = PostLikeForm::new(inserted_post.id, inserted_person.id, 1);
|
||||
let post_like_form = PostLikeForm::new(inserted_post.id, inserted_person.id, true);
|
||||
|
||||
let inserted_post_like = PostActions::like(pool, &post_like_form).await?;
|
||||
assert_eq!(Some(1), inserted_post_like.like_score);
|
||||
assert_eq!(Some(true), inserted_post_like.vote_is_upvote);
|
||||
|
||||
// Post Save
|
||||
let post_saved_form = PostSavedForm::new(inserted_post.id, inserted_person.id);
|
||||
@@ -800,7 +803,7 @@ mod tests {
|
||||
let inserted_child_comment =
|
||||
Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)).await?;
|
||||
|
||||
let post_like = PostLikeForm::new(inserted_post.id, inserted_person.id, 1);
|
||||
let post_like = PostLikeForm::new(inserted_post.id, inserted_person.id, true);
|
||||
|
||||
PostActions::like(pool, &post_like).await?;
|
||||
|
||||
@@ -812,7 +815,7 @@ mod tests {
|
||||
assert_eq!(0, post_aggs_before_delete.downvotes);
|
||||
|
||||
// Add a post dislike from the other person
|
||||
let post_dislike = PostLikeForm::new(inserted_post.id, another_inserted_person.id, -1);
|
||||
let post_dislike = PostLikeForm::new(inserted_post.id, another_inserted_person.id, false);
|
||||
|
||||
PostActions::like(pool, &post_dislike).await?;
|
||||
|
||||
|
||||
@@ -251,9 +251,9 @@ pub type Person2AliasAllColumnsTuple = (
|
||||
#[cfg(feature = "full")]
|
||||
/// A helper tuple for more my instance persons actions
|
||||
pub type MyInstancePersonsActionsAllColumnsTuple = (
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::blocked_communities_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::person_id>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::instance_id>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::blocked_communities_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::received_ban_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::ban_expires_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::blocked_persons_at>,
|
||||
|
||||
@@ -18,10 +18,10 @@ use serde_with::skip_serializing_none;
|
||||
#[cfg_attr(feature = "full", cursor_keys_module(name = person_liked_combined_keys))]
|
||||
/// A combined person_liked table.
|
||||
pub struct PersonLikedCombined {
|
||||
pub liked_at: DateTime<Utc>,
|
||||
pub like_score: i16,
|
||||
pub voted_at: DateTime<Utc>,
|
||||
pub id: PersonLikedCombinedId,
|
||||
pub person_id: PersonId,
|
||||
pub post_id: Option<PostId>,
|
||||
pub comment_id: Option<CommentId>,
|
||||
pub id: PersonLikedCombinedId,
|
||||
pub vote_is_upvote: bool,
|
||||
}
|
||||
|
||||
@@ -34,35 +34,3 @@ pub struct SearchCombined {
|
||||
pub id: SearchCombinedId,
|
||||
pub multi_community_id: Option<MultiCommunityId>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedPostInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub post_id: PostId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedCommentInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub comment_id: CommentId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedCommunityInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub community_id: CommunityId,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = search_combined))]
|
||||
pub struct SearchCombinedPersonInsertForm {
|
||||
pub published_at: DateTime<Utc>,
|
||||
pub score: i32,
|
||||
pub person_id: PersonId,
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ pub struct Comment {
|
||||
/// The total number of children in this comment branch.
|
||||
pub child_count: i32,
|
||||
#[serde(skip)]
|
||||
pub hot_rank: f64,
|
||||
pub hot_rank: f32,
|
||||
#[serde(skip)]
|
||||
pub controversy_rank: f64,
|
||||
pub controversy_rank: f32,
|
||||
pub report_count: i16,
|
||||
pub unresolved_report_count: i16,
|
||||
/// If a local user comments in a remote community, the comment is hidden until it is confirmed
|
||||
@@ -130,16 +130,16 @@ pub struct CommentUpdateForm {
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct CommentActions {
|
||||
/// When the comment was upvoted or downvoted.
|
||||
pub voted_at: Option<DateTime<Utc>>,
|
||||
/// When the comment was saved.
|
||||
pub saved_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub comment_id: CommentId,
|
||||
/// The like / score for the comment.
|
||||
pub like_score: Option<i16>,
|
||||
/// When the comment was liked.
|
||||
pub liked_at: Option<DateTime<Utc>>,
|
||||
/// When the comment was saved.
|
||||
pub saved_at: Option<DateTime<Utc>>,
|
||||
/// True if upvoted, false if downvoted. Upvote is greater than downvote.
|
||||
pub vote_is_upvote: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, derive_new::new)]
|
||||
@@ -151,9 +151,9 @@ pub struct CommentActions {
|
||||
pub struct CommentLikeForm {
|
||||
pub person_id: PersonId,
|
||||
pub comment_id: CommentId,
|
||||
pub like_score: i16,
|
||||
pub vote_is_upvote: bool,
|
||||
#[new(value = "Utc::now()")]
|
||||
pub liked_at: DateTime<Utc>,
|
||||
pub voted_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(derive_new::new)]
|
||||
|
||||
@@ -90,13 +90,13 @@ pub struct Community {
|
||||
/// The number of users with any activity in the last year.
|
||||
pub users_active_half_year: i32,
|
||||
#[serde(skip)]
|
||||
pub hot_rank: f64,
|
||||
pub hot_rank: f32,
|
||||
pub subscribers_local: i32,
|
||||
pub report_count: i16,
|
||||
pub unresolved_report_count: i16,
|
||||
/// Number of any interactions over the last month.
|
||||
#[serde(skip)]
|
||||
pub interactions_month: i32,
|
||||
pub report_count: i16,
|
||||
pub unresolved_report_count: i16,
|
||||
pub local_removed: bool,
|
||||
}
|
||||
|
||||
@@ -195,17 +195,8 @@ pub struct CommunityUpdateForm {
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct CommunityActions {
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub community_id: CommunityId,
|
||||
/// When the community was followed.
|
||||
pub followed_at: Option<DateTime<Utc>>,
|
||||
/// The state of the community follow.
|
||||
pub follow_state: Option<CommunityFollowerState>,
|
||||
/// The approver of the community follow.
|
||||
#[serde(skip)]
|
||||
pub follow_approver_id: Option<PersonId>,
|
||||
/// When the community was blocked.
|
||||
pub blocked_at: Option<DateTime<Utc>>,
|
||||
/// When this user became a moderator.
|
||||
@@ -214,6 +205,15 @@ pub struct CommunityActions {
|
||||
pub received_ban_at: Option<DateTime<Utc>>,
|
||||
/// When their ban expires.
|
||||
pub ban_expires_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub community_id: CommunityId,
|
||||
/// The state of the community follow.
|
||||
pub follow_state: Option<CommunityFollowerState>,
|
||||
/// The approver of the community follow.
|
||||
#[serde(skip)]
|
||||
pub follow_approver_id: Option<PersonId>,
|
||||
pub notifications: Option<CommunityNotificationsMode>,
|
||||
}
|
||||
|
||||
|
||||
@@ -55,12 +55,12 @@ pub struct InstanceForm {
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct InstanceActions {
|
||||
/// When the instance's communities were blocked.
|
||||
pub blocked_communities_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub instance_id: InstanceId,
|
||||
/// When the instance's communities were blocked.
|
||||
pub blocked_communities_at: Option<DateTime<Utc>>,
|
||||
/// When this user received a site ban.
|
||||
pub received_ban_at: Option<DateTime<Utc>>,
|
||||
/// When their ban expires.
|
||||
|
||||
@@ -134,16 +134,16 @@ pub struct PersonUpdateForm {
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct PersonActions {
|
||||
#[serde(skip)]
|
||||
pub followed_at: Option<DateTime<Utc>>,
|
||||
/// When the person was blocked.
|
||||
pub blocked_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub target_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub followed_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub follow_pending: Option<bool>,
|
||||
/// When the person was blocked.
|
||||
pub blocked_at: Option<DateTime<Utc>>,
|
||||
/// When the person was noted.
|
||||
pub noted_at: Option<DateTime<Utc>>,
|
||||
/// A note about the person.
|
||||
|
||||
@@ -62,24 +62,24 @@ pub struct Post {
|
||||
pub alt_text: Option<String>,
|
||||
/// Time at which the post will be published. None means publish immediately.
|
||||
pub scheduled_publish_time_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
/// A newest comment time, limited to 2 days, to prevent necrobumping
|
||||
pub newest_comment_time_necro_at: Option<DateTime<Utc>>,
|
||||
/// The time of the newest comment in the post, if the post has any comments.
|
||||
pub newest_comment_time_at: Option<DateTime<Utc>>,
|
||||
pub comments: i32,
|
||||
pub score: i32,
|
||||
pub upvotes: i32,
|
||||
pub downvotes: i32,
|
||||
#[serde(skip)]
|
||||
/// A newest comment time, limited to 2 days, to prevent necrobumping
|
||||
pub newest_comment_time_necro_at: DateTime<Utc>,
|
||||
/// The time of the newest comment in the post.
|
||||
pub newest_comment_time_at: DateTime<Utc>,
|
||||
pub hot_rank: f32,
|
||||
#[serde(skip)]
|
||||
pub hot_rank: f64,
|
||||
pub hot_rank_active: f32,
|
||||
#[serde(skip)]
|
||||
pub hot_rank_active: f64,
|
||||
#[serde(skip)]
|
||||
pub controversy_rank: f64,
|
||||
pub controversy_rank: f32,
|
||||
/// A rank that amplifies smaller communities
|
||||
#[serde(skip)]
|
||||
pub scaled_rank: f64,
|
||||
pub scaled_rank: f32,
|
||||
pub report_count: i16,
|
||||
pub unresolved_report_count: i16,
|
||||
/// If a local user posts in a remote community, the comment is hidden until it is confirmed
|
||||
@@ -191,25 +191,25 @@ pub struct PostUpdateForm {
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct PostActions {
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub post_id: PostId,
|
||||
/// When the post was read.
|
||||
pub read_at: Option<DateTime<Utc>>,
|
||||
/// When was the last time you read the comments.
|
||||
pub read_comments_at: Option<DateTime<Utc>>,
|
||||
/// When the post was saved.
|
||||
pub saved_at: Option<DateTime<Utc>>,
|
||||
/// When the post was upvoted or downvoted.
|
||||
pub voted_at: Option<DateTime<Utc>>,
|
||||
/// When the post was hidden.
|
||||
pub hidden_at: Option<DateTime<Utc>>,
|
||||
#[serde(skip)]
|
||||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub post_id: PostId,
|
||||
/// The number of comments you read last. Subtract this from total comments to get an unread
|
||||
/// count.
|
||||
pub read_comments_amount: Option<i32>,
|
||||
/// When the post was saved.
|
||||
pub saved_at: Option<DateTime<Utc>>,
|
||||
/// When the post was liked.
|
||||
pub liked_at: Option<DateTime<Utc>>,
|
||||
/// The like / score of the post.
|
||||
pub like_score: Option<i16>,
|
||||
/// When the post was hidden.
|
||||
pub hidden_at: Option<DateTime<Utc>>,
|
||||
/// True if upvoted, false if downvoted. Upvote is greater than downvote.
|
||||
pub vote_is_upvote: Option<bool>,
|
||||
pub notifications: Option<PostNotificationsMode>,
|
||||
}
|
||||
|
||||
@@ -222,9 +222,9 @@ pub struct PostActions {
|
||||
pub struct PostLikeForm {
|
||||
pub post_id: PostId,
|
||||
pub person_id: PersonId,
|
||||
pub like_score: i16,
|
||||
pub vote_is_upvote: bool,
|
||||
#[new(value = "Utc::now()")]
|
||||
pub liked_at: DateTime<Utc>,
|
||||
pub voted_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(derive_new::new)]
|
||||
|
||||
@@ -7,8 +7,11 @@ use crate::{
|
||||
use diesel::{
|
||||
associations::HasTable,
|
||||
dsl,
|
||||
expression::{Expression, Selectable},
|
||||
pg::Pg,
|
||||
query_builder::{DeleteStatement, IntoUpdateTarget},
|
||||
query_dsl::methods::{FindDsl, LimitDsl},
|
||||
query_dsl::methods::{FindDsl, LimitDsl, SelectDsl},
|
||||
SelectableHelper,
|
||||
Table,
|
||||
};
|
||||
use diesel_async::{
|
||||
@@ -34,14 +37,17 @@ pub type PrimaryKey<T> = <<T as HasTable>::Table as Table>::PrimaryKey;
|
||||
|
||||
// Trying to create default implementations for `create` and `update` results in a lifetime mess and
|
||||
// weird compile errors. https://github.com/rust-lang/rust/issues/102211
|
||||
pub trait Crud: HasTable + Sized
|
||||
pub trait Crud: HasTable + Sized + Selectable<Pg>
|
||||
where
|
||||
Self::Table: FindDsl<Self::IdType>,
|
||||
Find<Self>: LimitDsl + IntoUpdateTarget + Send,
|
||||
Find<Self>: LimitDsl + IntoUpdateTarget + SelectDsl<dsl::AsSelect<Self, Pg>> + Send,
|
||||
Delete<Find<Self>>: ExecuteDsl<AsyncPgConnection> + Send + 'static,
|
||||
dsl::Select<Find<Self>, dsl::AsSelect<Self, Pg>>: LimitDsl + Send,
|
||||
dsl::AsSelect<Self, Pg>: Expression,
|
||||
|
||||
// Used by `RunQueryDsl::first`
|
||||
dsl::Limit<Find<Self>>: LoadQuery<'static, AsyncPgConnection, Self> + Send + 'static,
|
||||
dsl::Limit<dsl::Select<Find<Self>, dsl::AsSelect<Self, Pg>>>:
|
||||
LoadQuery<'static, AsyncPgConnection, Self> + Send + 'static,
|
||||
{
|
||||
type InsertForm;
|
||||
type UpdateForm;
|
||||
@@ -57,7 +63,8 @@ where
|
||||
Self: Send,
|
||||
{
|
||||
async {
|
||||
let query: Find<Self> = Self::table().find(id);
|
||||
let query: dsl::Select<Find<Self>, dsl::AsSelect<Self, Pg>> =
|
||||
Self::table().find(id).select(Self::as_select());
|
||||
let conn = &mut *get_conn(pool).await?;
|
||||
query
|
||||
.first(conn)
|
||||
|
||||
@@ -60,7 +60,7 @@ const FETCH_LIMIT_DEFAULT: i64 = 20;
|
||||
pub const FETCH_LIMIT_MAX: usize = 50;
|
||||
pub const SITEMAP_LIMIT: i64 = 50000;
|
||||
pub const SITEMAP_DAYS: TimeDelta = TimeDelta::days(31);
|
||||
pub const RANK_DEFAULT: f64 = 0.0001;
|
||||
pub const RANK_DEFAULT: f32 = 0.0001;
|
||||
|
||||
pub type ActualDbPool = Pool<AsyncPgConnection>;
|
||||
|
||||
@@ -218,6 +218,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CoalesceKey<A, B>(pub A, pub B);
|
||||
|
||||
impl<A, B, C> CursorKey<C> for CoalesceKey<A, B>
|
||||
where
|
||||
A: CursorKey<C, SqlType = sql_types::Nullable<B::SqlType>>,
|
||||
B: CursorKey<C, SqlType: Send>,
|
||||
{
|
||||
type SqlType = B::SqlType;
|
||||
type CursorValue = functions::coalesce<B::SqlType, A::CursorValue, B::CursorValue>;
|
||||
type SqlValue = functions::coalesce<B::SqlType, A::SqlValue, B::SqlValue>;
|
||||
|
||||
fn get_cursor_value(cursor: &C) -> Self::CursorValue {
|
||||
// TODO: for slight optimization, use unwrap_or_else here (this requires the CursorKey trait to
|
||||
// be changed to allow non-binded CursorValue)
|
||||
functions::coalesce(A::get_cursor_value(cursor), B::get_cursor_value(cursor))
|
||||
}
|
||||
|
||||
fn get_sql_value() -> Self::SqlValue {
|
||||
functions::coalesce(A::get_sql_value(), B::get_sql_value())
|
||||
}
|
||||
}
|
||||
|
||||
/// Includes an SQL comment before `T`, which can be used to label auto_explain output
|
||||
#[derive(QueryId)]
|
||||
pub struct Commented<T> {
|
||||
@@ -490,12 +512,12 @@ pub mod functions {
|
||||
|
||||
define_sql_function! {
|
||||
#[sql_name = "r.hot_rank"]
|
||||
fn hot_rank(score: Int4, time: Timestamptz) -> Double;
|
||||
fn hot_rank(score: Int4, time: Timestamptz) -> Float;
|
||||
}
|
||||
|
||||
define_sql_function! {
|
||||
#[sql_name = "r.scaled_rank"]
|
||||
fn scaled_rank(score: Int4, time: Timestamptz, interactions_month: Int4) -> Double;
|
||||
fn scaled_rank(score: Int4, time: Timestamptz, interactions_month: Int4) -> Float;
|
||||
}
|
||||
|
||||
define_sql_function!(fn lower(x: Text) -> Text);
|
||||
@@ -572,18 +594,6 @@ pub(crate) fn format_actor_url(
|
||||
Ok(Url::parse(&url)?)
|
||||
}
|
||||
|
||||
/// Make sure the like score is 1, or -1
|
||||
///
|
||||
/// Uses a default NotFound error, that you should map to
|
||||
/// CouldntLikeComment/CouldntLikePost.
|
||||
pub(crate) fn validate_like(like_score: i16) -> LemmyResult<()> {
|
||||
if [-1, 1].contains(&like_score) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(LemmyErrorType::NotFound.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -315,12 +315,12 @@ pub fn post_select_remove_deletes() -> _ {
|
||||
post::url_content_type,
|
||||
post::alt_text,
|
||||
post::scheduled_publish_time_at,
|
||||
post::newest_comment_time_necro_at,
|
||||
post::newest_comment_time_at,
|
||||
post::comments,
|
||||
post::score,
|
||||
post::upvotes,
|
||||
post::downvotes,
|
||||
post::newest_comment_time_necro_at,
|
||||
post::newest_comment_time_at,
|
||||
post::hot_rank,
|
||||
post::hot_rank_active,
|
||||
post::controversy_rank,
|
||||
|
||||
@@ -184,8 +184,8 @@ diesel::table! {
|
||||
upvotes -> Int4,
|
||||
downvotes -> Int4,
|
||||
child_count -> Int4,
|
||||
hot_rank -> Float8,
|
||||
controversy_rank -> Float8,
|
||||
hot_rank -> Float4,
|
||||
controversy_rank -> Float4,
|
||||
report_count -> Int2,
|
||||
unresolved_report_count -> Int2,
|
||||
federation_pending -> Bool,
|
||||
@@ -195,11 +195,11 @@ diesel::table! {
|
||||
|
||||
diesel::table! {
|
||||
comment_actions (person_id, comment_id) {
|
||||
voted_at -> Nullable<Timestamptz>,
|
||||
saved_at -> Nullable<Timestamptz>,
|
||||
person_id -> Int4,
|
||||
comment_id -> Int4,
|
||||
like_score -> Nullable<Int2>,
|
||||
liked_at -> Nullable<Timestamptz>,
|
||||
saved_at -> Nullable<Timestamptz>,
|
||||
vote_is_upvote -> Nullable<Bool>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,11 +263,11 @@ diesel::table! {
|
||||
users_active_week -> Int4,
|
||||
users_active_month -> Int4,
|
||||
users_active_half_year -> Int4,
|
||||
hot_rank -> Float8,
|
||||
hot_rank -> Float4,
|
||||
subscribers_local -> Int4,
|
||||
interactions_month -> Int4,
|
||||
report_count -> Int2,
|
||||
unresolved_report_count -> Int2,
|
||||
interactions_month -> Int4,
|
||||
local_removed -> Bool,
|
||||
}
|
||||
}
|
||||
@@ -278,15 +278,15 @@ diesel::table! {
|
||||
use super::sql_types::CommunityNotificationsModeEnum;
|
||||
|
||||
community_actions (person_id, community_id) {
|
||||
person_id -> Int4,
|
||||
community_id -> Int4,
|
||||
followed_at -> Nullable<Timestamptz>,
|
||||
follow_state -> Nullable<CommunityFollowerState>,
|
||||
follow_approver_id -> Nullable<Int4>,
|
||||
blocked_at -> Nullable<Timestamptz>,
|
||||
became_moderator_at -> Nullable<Timestamptz>,
|
||||
received_ban_at -> Nullable<Timestamptz>,
|
||||
ban_expires_at -> Nullable<Timestamptz>,
|
||||
person_id -> Int4,
|
||||
community_id -> Int4,
|
||||
follow_state -> Nullable<CommunityFollowerState>,
|
||||
follow_approver_id -> Nullable<Int4>,
|
||||
notifications -> Nullable<CommunityNotificationsModeEnum>,
|
||||
}
|
||||
}
|
||||
@@ -410,9 +410,9 @@ diesel::table! {
|
||||
|
||||
diesel::table! {
|
||||
instance_actions (person_id, instance_id) {
|
||||
blocked_communities_at -> Nullable<Timestamptz>,
|
||||
person_id -> Int4,
|
||||
instance_id -> Int4,
|
||||
blocked_communities_at -> Nullable<Timestamptz>,
|
||||
received_ban_at -> Nullable<Timestamptz>,
|
||||
ban_expires_at -> Nullable<Timestamptz>,
|
||||
blocked_persons_at -> Nullable<Timestamptz>,
|
||||
@@ -866,11 +866,11 @@ diesel::table! {
|
||||
|
||||
diesel::table! {
|
||||
person_actions (person_id, target_id) {
|
||||
followed_at -> Nullable<Timestamptz>,
|
||||
blocked_at -> Nullable<Timestamptz>,
|
||||
person_id -> Int4,
|
||||
target_id -> Int4,
|
||||
followed_at -> Nullable<Timestamptz>,
|
||||
follow_pending -> Nullable<Bool>,
|
||||
blocked_at -> Nullable<Timestamptz>,
|
||||
noted_at -> Nullable<Timestamptz>,
|
||||
note -> Nullable<Text>,
|
||||
voted_at -> Nullable<Timestamptz>,
|
||||
@@ -890,12 +890,12 @@ diesel::table! {
|
||||
|
||||
diesel::table! {
|
||||
person_liked_combined (id) {
|
||||
liked_at -> Timestamptz,
|
||||
like_score -> Int2,
|
||||
voted_at -> Timestamptz,
|
||||
id -> Int4,
|
||||
person_id -> Int4,
|
||||
post_id -> Nullable<Int4>,
|
||||
comment_id -> Nullable<Int4>,
|
||||
id -> Int4,
|
||||
vote_is_upvote -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,16 +938,16 @@ diesel::table! {
|
||||
url_content_type -> Nullable<Text>,
|
||||
alt_text -> Nullable<Text>,
|
||||
scheduled_publish_time_at -> Nullable<Timestamptz>,
|
||||
newest_comment_time_necro_at -> Nullable<Timestamptz>,
|
||||
newest_comment_time_at -> Nullable<Timestamptz>,
|
||||
comments -> Int4,
|
||||
score -> Int4,
|
||||
upvotes -> Int4,
|
||||
downvotes -> Int4,
|
||||
newest_comment_time_necro_at -> Timestamptz,
|
||||
newest_comment_time_at -> Timestamptz,
|
||||
hot_rank -> Float8,
|
||||
hot_rank_active -> Float8,
|
||||
controversy_rank -> Float8,
|
||||
scaled_rank -> Float8,
|
||||
hot_rank -> Float4,
|
||||
hot_rank_active -> Float4,
|
||||
controversy_rank -> Float4,
|
||||
scaled_rank -> Float4,
|
||||
report_count -> Int2,
|
||||
unresolved_report_count -> Int2,
|
||||
federation_pending -> Bool,
|
||||
@@ -961,15 +961,15 @@ diesel::table! {
|
||||
use super::sql_types::PostNotificationsModeEnum;
|
||||
|
||||
post_actions (person_id, post_id) {
|
||||
person_id -> Int4,
|
||||
post_id -> Int4,
|
||||
read_at -> Nullable<Timestamptz>,
|
||||
read_comments_at -> Nullable<Timestamptz>,
|
||||
read_comments_amount -> Nullable<Int4>,
|
||||
saved_at -> Nullable<Timestamptz>,
|
||||
liked_at -> Nullable<Timestamptz>,
|
||||
like_score -> Nullable<Int2>,
|
||||
voted_at -> Nullable<Timestamptz>,
|
||||
hidden_at -> Nullable<Timestamptz>,
|
||||
person_id -> Int4,
|
||||
post_id -> Int4,
|
||||
read_comments_amount -> Nullable<Int4>,
|
||||
vote_is_upvote -> Nullable<Bool>,
|
||||
notifications -> Nullable<PostNotificationsModeEnum>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ BEGIN
|
||||
score = a.score + diff.upvotes - diff.downvotes, upvotes = a.upvotes + diff.upvotes, downvotes = a.downvotes + diff.downvotes, controversy_rank = r.controversy_rank ((a.upvotes + diff.upvotes)::numeric, (a.downvotes + diff.downvotes)::numeric)
|
||||
FROM (
|
||||
SELECT
|
||||
(thing_actions).thing_id, coalesce(sum(count_diff) FILTER (WHERE (thing_actions).like_score = 1), 0) AS upvotes, coalesce(sum(count_diff) FILTER (WHERE (thing_actions).like_score != 1), 0) AS downvotes FROM select_old_and_new_rows AS old_and_new_rows
|
||||
WHERE (thing_actions).like_score IS NOT NULL GROUP BY (thing_actions).thing_id) AS diff
|
||||
(thing_actions).thing_id, coalesce(sum(count_diff) FILTER (WHERE (thing_actions).vote_is_upvote), 0) AS upvotes, coalesce(sum(count_diff) FILTER (WHERE NOT (thing_actions).vote_is_upvote), 0) AS downvotes FROM select_old_and_new_rows AS old_and_new_rows
|
||||
WHERE (thing_actions).vote_is_upvote IS NOT NULL GROUP BY (thing_actions).thing_id) AS diff
|
||||
WHERE
|
||||
a.id = diff.thing_id
|
||||
AND (diff.upvotes, diff.downvotes) != (0, 0)
|
||||
@@ -370,9 +370,6 @@ BEGIN
|
||||
IF NEW.local THEN
|
||||
NEW.ap_id = coalesce(NEW.ap_id, r.local_url ('/post/' || NEW.id::text));
|
||||
END IF;
|
||||
-- Set aggregates
|
||||
NEW.newest_comment_time_at = NEW.published_at;
|
||||
NEW.newest_comment_time_necro_at = NEW.published_at;
|
||||
RETURN NEW;
|
||||
END
|
||||
$$;
|
||||
@@ -516,26 +513,26 @@ BEGIN
|
||||
WHERE p.person_id = OLD.person_id
|
||||
AND p.thing_id = OLD.thing_id;
|
||||
ELSIF (TG_OP = 'INSERT') THEN
|
||||
IF NEW.liked_at IS NOT NULL AND (
|
||||
IF NEW.voted_at IS NOT NULL AND (
|
||||
SELECT
|
||||
local
|
||||
FROM
|
||||
person
|
||||
WHERE
|
||||
id = NEW.person_id) = TRUE THEN
|
||||
INSERT INTO person_liked_combined (liked_at, like_score, person_id, thing_id)
|
||||
VALUES (NEW.liked_at, NEW.like_score, NEW.person_id, NEW.thing_id);
|
||||
INSERT INTO person_liked_combined (voted_at, vote_is_upvote, person_id, thing_id)
|
||||
VALUES (NEW.voted_at, NEW.vote_is_upvote, NEW.person_id, NEW.thing_id);
|
||||
END IF;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
IF NEW.liked_at IS NOT NULL AND (
|
||||
IF NEW.voted_at IS NOT NULL AND (
|
||||
SELECT
|
||||
local
|
||||
FROM
|
||||
person
|
||||
WHERE
|
||||
id = NEW.person_id) = TRUE THEN
|
||||
INSERT INTO person_liked_combined (liked_at, like_score, person_id, thing_id)
|
||||
VALUES (NEW.liked_at, NEW.like_score, NEW.person_id, NEW.thing_id);
|
||||
INSERT INTO person_liked_combined (voted_at, vote_is_upvote, person_id, thing_id)
|
||||
VALUES (NEW.voted_at, NEW.vote_is_upvote, NEW.person_id, NEW.thing_id);
|
||||
-- If liked gets set as null, delete the row
|
||||
ELSE
|
||||
DELETE FROM person_liked_combined AS p
|
||||
@@ -546,7 +543,7 @@ BEGIN
|
||||
RETURN NULL;
|
||||
END $$;
|
||||
CREATE TRIGGER person_liked_combined
|
||||
AFTER INSERT OR DELETE OR UPDATE OF liked_at ON thing_actions
|
||||
AFTER INSERT OR DELETE OR UPDATE OF voted_at ON thing_actions
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION r.person_liked_combined_change_values_thing ( );
|
||||
$b$,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Each calculation used in triggers should be a single SQL language
|
||||
-- expression so it can be inlined in migrations.
|
||||
CREATE FUNCTION r.controversy_rank (upvotes numeric, downvotes numeric)
|
||||
RETURNS float
|
||||
RETURNS real
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE RETURN CASE WHEN downvotes <= 0
|
||||
OR upvotes <= 0 THEN
|
||||
@@ -16,7 +16,7 @@ CREATE FUNCTION r.controversy_rank (upvotes numeric, downvotes numeric)
|
||||
END;
|
||||
|
||||
CREATE FUNCTION r.hot_rank (score numeric, published_at timestamp with time zone)
|
||||
RETURNS double precision
|
||||
RETURNS real
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE RETURN
|
||||
-- after a week, it will default to 0.
|
||||
@@ -34,7 +34,7 @@ now() - published_at) < '7 days' THEN
|
||||
END;
|
||||
|
||||
CREATE FUNCTION r.scaled_rank (score numeric, published_at timestamp with time zone, interactions_month numeric)
|
||||
RETURNS double precision
|
||||
RETURNS real
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE
|
||||
-- Add 2 to avoid divide by zero errors
|
||||
@@ -154,14 +154,14 @@ $a$;
|
||||
-- Edit community aggregates to include voters as active users
|
||||
CREATE OR REPLACE FUNCTION r.community_aggregates_activity (i text)
|
||||
RETURNS TABLE (
|
||||
count_ bigint,
|
||||
count_ integer,
|
||||
community_id_ integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN query
|
||||
SELECT
|
||||
count(*),
|
||||
count(*)::integer,
|
||||
community_id
|
||||
FROM (
|
||||
SELECT
|
||||
@@ -193,7 +193,7 @@ BEGIN
|
||||
INNER JOIN post p ON pa.post_id = p.id
|
||||
INNER JOIN person pe ON pa.person_id = pe.id
|
||||
WHERE
|
||||
pa.liked_at > ('now'::timestamp - i::interval)
|
||||
pa.voted_at > ('now'::timestamp - i::interval)
|
||||
AND pe.bot_account = FALSE
|
||||
UNION
|
||||
SELECT
|
||||
@@ -205,7 +205,7 @@ BEGIN
|
||||
INNER JOIN post p ON c.post_id = p.id
|
||||
INNER JOIN person pe ON ca.person_id = pe.id
|
||||
WHERE
|
||||
ca.liked_at > ('now'::timestamp - i::interval)
|
||||
ca.voted_at > ('now'::timestamp - i::interval)
|
||||
AND pe.bot_account = FALSE) a
|
||||
GROUP BY
|
||||
community_id;
|
||||
@@ -215,14 +215,14 @@ $$;
|
||||
-- Community aggregate function for adding up total number of interactions
|
||||
CREATE OR REPLACE FUNCTION r.community_aggregates_interactions (i text)
|
||||
RETURNS TABLE (
|
||||
count_ bigint,
|
||||
count_ integer,
|
||||
community_id_ integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN query
|
||||
SELECT
|
||||
COALESCE(sum(comments + upvotes + downvotes)::bigint, 0) AS count_,
|
||||
COALESCE(sum(comments + upvotes + downvotes)::integer, 0) AS count_,
|
||||
community_id AS community_id_
|
||||
FROM
|
||||
post
|
||||
@@ -270,7 +270,7 @@ BEGIN
|
||||
post_actions pa
|
||||
INNER JOIN person pe ON pa.person_id = pe.id
|
||||
WHERE
|
||||
pa.liked_at > ('now'::timestamp - i::interval)
|
||||
pa.voted_at > ('now'::timestamp - i::interval)
|
||||
AND pe.local = TRUE
|
||||
AND pe.bot_account = FALSE
|
||||
UNION
|
||||
@@ -280,7 +280,7 @@ BEGIN
|
||||
comment_actions ca
|
||||
INNER JOIN person pe ON ca.person_id = pe.id
|
||||
WHERE
|
||||
ca.liked_at > ('now'::timestamp - i::interval)
|
||||
ca.voted_at > ('now'::timestamp - i::interval)
|
||||
AND pe.local = TRUE
|
||||
AND pe.bot_account = FALSE) a;
|
||||
RETURN count_;
|
||||
|
||||
@@ -32,8 +32,7 @@ pub struct CreateComment {
|
||||
/// Like a comment.
|
||||
pub struct CreateCommentLike {
|
||||
pub comment_id: CommentId,
|
||||
/// Must be -1, 0, or 1 .
|
||||
pub score: i16,
|
||||
pub is_upvote: Option<bool>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
|
||||
@@ -457,7 +457,7 @@ mod tests {
|
||||
)
|
||||
);
|
||||
|
||||
let comment_like_form = CommentLikeForm::new(inserted_timmy_person.id, comment_0.id, 1);
|
||||
let comment_like_form = CommentLikeForm::new(inserted_timmy_person.id, comment_0.id, true);
|
||||
|
||||
CommentActions::like(pool, &comment_like_form).await?;
|
||||
|
||||
@@ -513,7 +513,7 @@ mod tests {
|
||||
assert!(read_comment_views_with_person[0]
|
||||
.comment_actions
|
||||
.as_ref()
|
||||
.is_some_and(|x| x.like_score == Some(1)));
|
||||
.is_some_and(|x| x.vote_is_upvote == Some(true)));
|
||||
assert!(read_comment_views_with_person[0].can_mod);
|
||||
|
||||
// Make sure its 1, not showing the blocked comment
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::{
|
||||
PostView,
|
||||
};
|
||||
use diesel::{
|
||||
dsl::not,
|
||||
BoolExpressionMethods,
|
||||
ExpressionMethods,
|
||||
JoinOnDsl,
|
||||
@@ -179,8 +180,8 @@ impl PersonLikedCombinedQuery {
|
||||
if let Some(like_type) = self.like_type {
|
||||
query = match like_type {
|
||||
LikeType::All => query,
|
||||
LikeType::LikedOnly => query.filter(person_liked_combined::like_score.eq(1)),
|
||||
LikeType::DislikedOnly => query.filter(person_liked_combined::like_score.eq(-1)),
|
||||
LikeType::LikedOnly => query.filter(person_liked_combined::vote_is_upvote),
|
||||
LikeType::DislikedOnly => query.filter(not(person_liked_combined::vote_is_upvote)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +193,7 @@ impl PersonLikedCombinedQuery {
|
||||
None,
|
||||
self.page_back,
|
||||
)
|
||||
.then_order_by(key::liked_at)
|
||||
.then_order_by(key::voted_at)
|
||||
// Tie breaker
|
||||
.then_order_by(key::id);
|
||||
|
||||
@@ -366,13 +367,13 @@ mod tests {
|
||||
assert_eq!(0, timmy_liked.len());
|
||||
|
||||
// Like a few things
|
||||
let like_sara_comment_2 = CommentLikeForm::new(data.timmy.id, data.sara_comment_2.id, 1);
|
||||
let like_sara_comment_2 = CommentLikeForm::new(data.timmy.id, data.sara_comment_2.id, true);
|
||||
CommentActions::like(pool, &like_sara_comment_2).await?;
|
||||
|
||||
let dislike_sara_comment = CommentLikeForm::new(data.timmy.id, data.sara_comment.id, -1);
|
||||
let dislike_sara_comment = CommentLikeForm::new(data.timmy.id, data.sara_comment.id, false);
|
||||
CommentActions::like(pool, &dislike_sara_comment).await?;
|
||||
|
||||
let post_like_form = PostLikeForm::new(data.timmy_post.id, data.timmy.id, 1);
|
||||
let post_like_form = PostLikeForm::new(data.timmy_post.id, data.timmy.id, true);
|
||||
PostActions::like(pool, &post_like_form).await?;
|
||||
|
||||
let timmy_liked_all = PersonLikedCombinedQuery::default()
|
||||
@@ -384,7 +385,10 @@ mod tests {
|
||||
if let PersonLikedCombinedView::Post(v) = &timmy_liked_all[0] {
|
||||
assert_eq!(data.timmy_post.id, v.post.id);
|
||||
assert_eq!(data.timmy.id, v.post.creator_id);
|
||||
assert_eq!(Some(1), v.post_actions.as_ref().and_then(|l| l.like_score));
|
||||
assert_eq!(
|
||||
Some(true),
|
||||
v.post_actions.as_ref().and_then(|l| l.vote_is_upvote)
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
}
|
||||
@@ -392,8 +396,8 @@ mod tests {
|
||||
assert_eq!(data.sara_comment.id, v.comment.id);
|
||||
assert_eq!(data.sara.id, v.comment.creator_id);
|
||||
assert_eq!(
|
||||
Some(-1),
|
||||
v.comment_actions.as_ref().and_then(|l| l.like_score)
|
||||
Some(false),
|
||||
v.comment_actions.as_ref().and_then(|l| l.vote_is_upvote)
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
@@ -402,8 +406,8 @@ mod tests {
|
||||
assert_eq!(data.sara_comment_2.id, v.comment.id);
|
||||
assert_eq!(data.sara.id, v.comment.creator_id);
|
||||
assert_eq!(
|
||||
Some(1),
|
||||
v.comment_actions.as_ref().and_then(|l| l.like_score)
|
||||
Some(true),
|
||||
v.comment_actions.as_ref().and_then(|l| l.vote_is_upvote)
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
@@ -421,8 +425,8 @@ mod tests {
|
||||
assert_eq!(data.sara_comment.id, v.comment.id);
|
||||
assert_eq!(data.sara.id, v.comment.creator_id);
|
||||
assert_eq!(
|
||||
Some(-1),
|
||||
v.comment_actions.as_ref().and_then(|l| l.like_score)
|
||||
Some(false),
|
||||
v.comment_actions.as_ref().and_then(|l| l.vote_is_upvote)
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
|
||||
@@ -38,8 +38,7 @@ pub struct CreatePost {
|
||||
/// Like a post.
|
||||
pub struct CreatePostLike {
|
||||
pub post_id: PostId,
|
||||
/// Score must be -1, 0, or 1.
|
||||
pub score: i16,
|
||||
pub is_upvote: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -53,6 +53,7 @@ use lemmy_db_schema::{
|
||||
},
|
||||
},
|
||||
seconds_to_pg_interval,
|
||||
CoalesceKey,
|
||||
Commented,
|
||||
DbPool,
|
||||
},
|
||||
@@ -529,7 +530,7 @@ impl PostQuery<'_> {
|
||||
Scaled => pq.then_order_by(key::scaled_rank),
|
||||
Controversial => pq.then_order_by(key::controversy_rank),
|
||||
New | Old => pq.then_order_by(key::published_at),
|
||||
NewComments => pq.then_order_by(key::newest_comment_time_at),
|
||||
NewComments => pq.then_order_by(CoalesceKey(key::newest_comment_time_at, key::published_at)),
|
||||
MostComments => pq.then_order_by(key::comments),
|
||||
Top => pq.then_order_by(key::score),
|
||||
};
|
||||
@@ -971,16 +972,16 @@ mod tests {
|
||||
let pool = &data.pool();
|
||||
let pool = &mut pool.into();
|
||||
|
||||
let post_like_form = PostLikeForm::new(data.post.id, data.tegan.person.id, 1);
|
||||
let post_like_form = PostLikeForm::new(data.post.id, data.tegan.person.id, true);
|
||||
|
||||
let inserted_post_like = PostActions::like(pool, &post_like_form).await?;
|
||||
|
||||
assert_eq!(
|
||||
(data.post.id, data.tegan.person.id, Some(1)),
|
||||
(data.post.id, data.tegan.person.id, Some(true)),
|
||||
(
|
||||
inserted_post_like.post_id,
|
||||
inserted_post_like.person_id,
|
||||
inserted_post_like.like_score,
|
||||
inserted_post_like.vote_is_upvote,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -998,7 +999,7 @@ mod tests {
|
||||
(
|
||||
post_listing_single_with_person
|
||||
.post_actions
|
||||
.is_some_and(|t| t.like_score == Some(1)),
|
||||
.is_some_and(|t| t.vote_is_upvote == Some(true)),
|
||||
// Make sure person actions is none so you don't get a voted_at for your own user
|
||||
post_listing_single_with_person.person_actions.is_none(),
|
||||
post_listing_single_with_person.post.score,
|
||||
@@ -1094,20 +1095,20 @@ mod tests {
|
||||
);
|
||||
let bot_post_2 = Post::create(pool, &bot_post_2).await?;
|
||||
|
||||
let post_like_form = PostLikeForm::new(data.bot_post.id, data.tegan.person.id, 1);
|
||||
let post_like_form = PostLikeForm::new(data.bot_post.id, data.tegan.person.id, true);
|
||||
let inserted_post_like = PostActions::like(pool, &post_like_form).await?;
|
||||
|
||||
assert_eq!(
|
||||
(data.bot_post.id, data.tegan.person.id, Some(1)),
|
||||
(data.bot_post.id, data.tegan.person.id, Some(true)),
|
||||
(
|
||||
inserted_post_like.post_id,
|
||||
inserted_post_like.person_id,
|
||||
inserted_post_like.like_score,
|
||||
inserted_post_like.vote_is_upvote,
|
||||
)
|
||||
);
|
||||
|
||||
let inserted_person_like =
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, 1).await?;
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, true).await?;
|
||||
|
||||
assert_eq!(
|
||||
(data.tegan.person.id, data.bot.person.id, Some(1), Some(0),),
|
||||
@@ -1133,7 +1134,7 @@ mod tests {
|
||||
(
|
||||
post_listing
|
||||
.post_actions
|
||||
.is_some_and(|t| t.like_score == Some(1)),
|
||||
.is_some_and(|t| t.vote_is_upvote == Some(true)),
|
||||
post_listing
|
||||
.person_actions
|
||||
.as_ref()
|
||||
@@ -1149,10 +1150,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Do a 2nd like to another post
|
||||
let post_2_like_form = PostLikeForm::new(bot_post_2.id, data.tegan.person.id, 1);
|
||||
let post_2_like_form = PostLikeForm::new(bot_post_2.id, data.tegan.person.id, true);
|
||||
let _inserted_post_2_like = PostActions::like(pool, &post_2_like_form).await?;
|
||||
let inserted_person_like_2 =
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, 1).await?;
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, true).await?;
|
||||
assert_eq!(
|
||||
(data.tegan.person.id, data.bot.person.id, Some(2), Some(0),),
|
||||
(
|
||||
@@ -1169,7 +1170,7 @@ mod tests {
|
||||
assert_eq!(UpleteCount::only_deleted(1), like_removed);
|
||||
|
||||
let person_like_removed =
|
||||
PersonActions::remove_like(pool, data.tegan.person.id, data.bot.person.id, 1).await?;
|
||||
PersonActions::remove_like(pool, data.tegan.person.id, data.bot.person.id, true).await?;
|
||||
assert_eq!(
|
||||
(data.tegan.person.id, data.bot.person.id, Some(1), Some(0),),
|
||||
(
|
||||
@@ -1181,10 +1182,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Now do a downvote
|
||||
let post_like_form = PostLikeForm::new(data.bot_post.id, data.tegan.person.id, -1);
|
||||
let post_like_form = PostLikeForm::new(data.bot_post.id, data.tegan.person.id, false);
|
||||
let _inserted_post_dislike = PostActions::like(pool, &post_like_form).await?;
|
||||
let inserted_person_dislike =
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, -1).await?;
|
||||
PersonActions::like(pool, data.tegan.person.id, data.bot.person.id, false).await?;
|
||||
assert_eq!(
|
||||
(data.tegan.person.id, data.bot.person.id, Some(1), Some(1),),
|
||||
(
|
||||
@@ -1209,7 +1210,7 @@ mod tests {
|
||||
(
|
||||
post_listing
|
||||
.post_actions
|
||||
.is_some_and(|t| t.like_score == Some(-1)),
|
||||
.is_some_and(|t| t.vote_is_upvote == Some(false)),
|
||||
post_listing
|
||||
.person_actions
|
||||
.as_ref()
|
||||
|
||||
@@ -290,25 +290,25 @@ impl SearchCombinedQuery {
|
||||
// Liked / disliked filter
|
||||
if let Some(my_id) = my_person_id {
|
||||
let not_creator_filter = item_creator.ne(my_id);
|
||||
let liked_disliked_filter = |score: i16| {
|
||||
let liked_disliked_filter = |should_be_upvote: bool| {
|
||||
search_combined::post_id
|
||||
.is_not_null()
|
||||
.and(post_actions::like_score.eq(score))
|
||||
.and(post_actions::vote_is_upvote.eq(should_be_upvote))
|
||||
.or(
|
||||
search_combined::comment_id
|
||||
.is_not_null()
|
||||
.and(comment_actions::like_score.eq(score)),
|
||||
.and(comment_actions::vote_is_upvote.eq(should_be_upvote)),
|
||||
)
|
||||
};
|
||||
|
||||
if self.liked_only.unwrap_or_default() {
|
||||
query = query
|
||||
.filter(not_creator_filter)
|
||||
.filter(liked_disliked_filter(1));
|
||||
.filter(liked_disliked_filter(true));
|
||||
} else if self.disliked_only.unwrap_or_default() {
|
||||
query = query
|
||||
.filter(not_creator_filter)
|
||||
.filter(liked_disliked_filter(-1));
|
||||
.filter(liked_disliked_filter(false));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -609,22 +609,22 @@ mod tests {
|
||||
let comment_in_nsfw_post = Comment::create(pool, &comment_in_nsfw_post_form, None).await?;
|
||||
|
||||
// Timmy likes and dislikes a few things
|
||||
let timmy_like_post_form = PostLikeForm::new(timmy_post.id, timmy.id, 1);
|
||||
let timmy_like_post_form = PostLikeForm::new(timmy_post.id, timmy.id, true);
|
||||
PostActions::like(pool, &timmy_like_post_form).await?;
|
||||
|
||||
let timmy_like_sara_post_form = PostLikeForm::new(sara_post.id, timmy.id, 1);
|
||||
let timmy_like_sara_post_form = PostLikeForm::new(sara_post.id, timmy.id, true);
|
||||
PostActions::like(pool, &timmy_like_sara_post_form).await?;
|
||||
|
||||
let timmy_dislike_post_form = PostLikeForm::new(timmy_post_2.id, timmy.id, -1);
|
||||
let timmy_dislike_post_form = PostLikeForm::new(timmy_post_2.id, timmy.id, false);
|
||||
PostActions::like(pool, &timmy_dislike_post_form).await?;
|
||||
|
||||
let timmy_like_comment_form = CommentLikeForm::new(timmy.id, timmy_comment.id, 1);
|
||||
let timmy_like_comment_form = CommentLikeForm::new(timmy.id, timmy_comment.id, true);
|
||||
CommentActions::like(pool, &timmy_like_comment_form).await?;
|
||||
|
||||
let timmy_like_sara_comment_form = CommentLikeForm::new(timmy.id, sara_comment.id, 1);
|
||||
let timmy_like_sara_comment_form = CommentLikeForm::new(timmy.id, sara_comment.id, true);
|
||||
CommentActions::like(pool, &timmy_like_sara_comment_form).await?;
|
||||
|
||||
let timmy_dislike_sara_comment_form = CommentLikeForm::new(timmy.id, sara_comment_2.id, -1);
|
||||
let timmy_dislike_sara_comment_form = CommentLikeForm::new(timmy.id, sara_comment_2.id, false);
|
||||
CommentActions::like(pool, &timmy_dislike_sara_comment_form).await?;
|
||||
|
||||
Ok(Data {
|
||||
|
||||
@@ -85,7 +85,7 @@ impl VoteView {
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.filter(post_actions::post_id.eq(post_id))
|
||||
.filter(post_actions::like_score.is_not_null())
|
||||
.filter(post_actions::vote_is_upvote.is_not_null())
|
||||
.select((
|
||||
person::all_columns,
|
||||
creator_local_home_banned(),
|
||||
@@ -93,16 +93,16 @@ impl VoteView {
|
||||
.field(community_actions::received_ban_at)
|
||||
.nullable()
|
||||
.is_not_null(),
|
||||
post_actions::like_score.assume_not_null(),
|
||||
post_actions::vote_is_upvote.assume_not_null(),
|
||||
))
|
||||
.limit(limit)
|
||||
.into_boxed();
|
||||
|
||||
// Sorting by like score
|
||||
let paginated_query = paginate(query, SortDirection::Asc, cursor_data, None, page_back)
|
||||
.then_order_by(key::like_score)
|
||||
.then_order_by(key::vote_is_upvote)
|
||||
// Tie breaker
|
||||
.then_order_by(key::liked_at);
|
||||
.then_order_by(key::voted_at);
|
||||
|
||||
paginated_query
|
||||
.load::<Self>(conn)
|
||||
@@ -159,7 +159,7 @@ impl VoteView {
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.filter(comment_actions::comment_id.eq(comment_id))
|
||||
.filter(comment_actions::like_score.is_not_null())
|
||||
.filter(comment_actions::vote_is_upvote.is_not_null())
|
||||
.select((
|
||||
person::all_columns,
|
||||
creator_local_home_banned(),
|
||||
@@ -167,16 +167,16 @@ impl VoteView {
|
||||
.field(community_actions::received_ban_at)
|
||||
.nullable()
|
||||
.is_not_null(),
|
||||
comment_actions::like_score.assume_not_null(),
|
||||
comment_actions::vote_is_upvote.assume_not_null(),
|
||||
))
|
||||
.limit(limit)
|
||||
.into_boxed();
|
||||
|
||||
// Sorting by like score
|
||||
let paginated_query = paginate(query, SortDirection::Asc, cursor_data, None, page_back)
|
||||
.then_order_by(key::like_score)
|
||||
.then_order_by(key::vote_is_upvote)
|
||||
// Tie breaker
|
||||
.then_order_by(key::liked_at);
|
||||
.then_order_by(key::voted_at);
|
||||
|
||||
paginated_query
|
||||
.load::<Self>(conn)
|
||||
@@ -243,11 +243,11 @@ mod tests {
|
||||
let inserted_comment = Comment::create(pool, &comment_form, None).await?;
|
||||
|
||||
// Timmy upvotes his own post
|
||||
let timmy_post_vote_form = PostLikeForm::new(inserted_post.id, inserted_timmy.id, 1);
|
||||
let timmy_post_vote_form = PostLikeForm::new(inserted_post.id, inserted_timmy.id, true);
|
||||
PostActions::like(pool, &timmy_post_vote_form).await?;
|
||||
|
||||
// Sara downvotes timmy's post
|
||||
let sara_post_vote_form = PostLikeForm::new(inserted_post.id, inserted_sara.id, -1);
|
||||
let sara_post_vote_form = PostLikeForm::new(inserted_post.id, inserted_sara.id, false);
|
||||
PostActions::like(pool, &sara_post_vote_form).await?;
|
||||
|
||||
let mut expected_post_vote_views = [
|
||||
@@ -255,13 +255,13 @@ mod tests {
|
||||
creator: inserted_sara.clone(),
|
||||
creator_banned: false,
|
||||
creator_banned_from_community: false,
|
||||
score: -1,
|
||||
is_upvote: false,
|
||||
},
|
||||
VoteView {
|
||||
creator: inserted_timmy.clone(),
|
||||
creator_banned: false,
|
||||
creator_banned_from_community: false,
|
||||
score: 1,
|
||||
is_upvote: true,
|
||||
},
|
||||
];
|
||||
expected_post_vote_views[1].creator.post_count = 1;
|
||||
@@ -272,11 +272,12 @@ mod tests {
|
||||
assert_eq!(read_post_vote_views, expected_post_vote_views);
|
||||
|
||||
// Timothy votes down his own comment
|
||||
let timmy_comment_vote_form = CommentLikeForm::new(inserted_timmy.id, inserted_comment.id, -1);
|
||||
let timmy_comment_vote_form =
|
||||
CommentLikeForm::new(inserted_timmy.id, inserted_comment.id, false);
|
||||
CommentActions::like(pool, &timmy_comment_vote_form).await?;
|
||||
|
||||
// Sara upvotes timmy's comment
|
||||
let sara_comment_vote_form = CommentLikeForm::new(inserted_sara.id, inserted_comment.id, 1);
|
||||
let sara_comment_vote_form = CommentLikeForm::new(inserted_sara.id, inserted_comment.id, true);
|
||||
CommentActions::like(pool, &sara_comment_vote_form).await?;
|
||||
|
||||
let mut expected_comment_vote_views = [
|
||||
@@ -284,13 +285,13 @@ mod tests {
|
||||
creator: inserted_timmy.clone(),
|
||||
creator_banned: false,
|
||||
creator_banned_from_community: false,
|
||||
score: -1,
|
||||
is_upvote: false,
|
||||
},
|
||||
VoteView {
|
||||
creator: inserted_sara.clone(),
|
||||
creator_banned: false,
|
||||
creator_banned_from_community: false,
|
||||
score: 1,
|
||||
is_upvote: true,
|
||||
},
|
||||
];
|
||||
expected_comment_vote_views[0].creator.post_count = 1;
|
||||
|
||||
@@ -18,5 +18,5 @@ pub struct VoteView {
|
||||
pub creator: Person,
|
||||
pub creator_banned: bool,
|
||||
pub creator_banned_from_community: bool,
|
||||
pub score: i16,
|
||||
pub is_upvote: bool,
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use diesel::{
|
||||
NullableExpressionMethods,
|
||||
QueryDsl,
|
||||
QueryableByName,
|
||||
SelectableHelper,
|
||||
};
|
||||
use diesel_async::{AsyncPgConnection, RunQueryDsl};
|
||||
use diesel_uplete::uplete;
|
||||
@@ -250,7 +251,7 @@ async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection)
|
||||
FOR UPDATE SKIP LOCKED)
|
||||
UPDATE post pa
|
||||
SET hot_rank = r.hot_rank(pa.score, pa.published_at),
|
||||
hot_rank_active = r.hot_rank(pa.score, pa.newest_comment_time_necro_at),
|
||||
hot_rank_active = r.hot_rank(pa.score, coalesce(pa.newest_comment_time_necro_at, pa.published_at)),
|
||||
scaled_rank = r.scaled_rank(pa.score, pa.published_at, ca.interactions_month)
|
||||
FROM batch, community ca
|
||||
WHERE pa.id = batch.id
|
||||
@@ -593,7 +594,7 @@ async fn publish_scheduled_posts(context: &Data<LemmyContext>) -> LemmyResult<()
|
||||
.filter(not(exists(not_community_banned_action)))
|
||||
// ensure that user isnt banned from local
|
||||
.filter(not(exists(not_local_banned_action)))
|
||||
.select((post::all_columns, community::all_columns))
|
||||
.select((Post::as_select(), Community::as_select()))
|
||||
.get_results::<(Post, Community)>(conn)
|
||||
.await?;
|
||||
|
||||
@@ -771,7 +772,7 @@ mod tests {
|
||||
&PostInsertForm::new("i am grrreat".to_owned(), person.id, community.id),
|
||||
)
|
||||
.await?;
|
||||
PostActions::like(pool, &PostLikeForm::new(post.id, person.id, 1)).await?;
|
||||
PostActions::like(pool, &PostLikeForm::new(post.id, person.id, true)).await?;
|
||||
|
||||
active_counts(pool, ONE_DAY).await?;
|
||||
all_active_counts(pool).await?;
|
||||
|
||||
@@ -134,7 +134,11 @@ INSERT INTO post_like (post_id, person_id, score, published)
|
||||
SELECT
|
||||
post_id,
|
||||
person_id,
|
||||
like_score,
|
||||
CASE WHEN vote_is_upvote THEN
|
||||
1
|
||||
ELSE
|
||||
-1
|
||||
END,
|
||||
liked
|
||||
FROM
|
||||
post_actions
|
||||
@@ -186,7 +190,11 @@ INSERT INTO comment_like (comment_id, person_id, score, published)
|
||||
SELECT
|
||||
comment_id,
|
||||
person_id,
|
||||
like_score,
|
||||
CASE WHEN vote_is_upvote THEN
|
||||
1
|
||||
ELSE
|
||||
-1
|
||||
END,
|
||||
liked
|
||||
FROM
|
||||
comment_actions
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
-- comment_actions
|
||||
CREATE TABLE comment_actions AS
|
||||
SELECT
|
||||
max(liked) AS liked,
|
||||
max(saved) AS saved,
|
||||
person_id,
|
||||
comment_id,
|
||||
cast(max(like_score) AS smallint) AS like_score,
|
||||
max(liked) AS liked,
|
||||
max(saved) AS saved
|
||||
max(like_score) = 1 AS vote_is_upvote -- `null = 1` returns null
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
@@ -42,17 +42,17 @@ ALTER TABLE comment_actions
|
||||
ADD PRIMARY KEY (person_id, comment_id),
|
||||
ADD CONSTRAINT comment_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT comment_actions_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT comment_actions_check_liked CHECK (((liked IS NULL) = (like_score IS NULL)));
|
||||
ADD CONSTRAINT comment_actions_check_liked CHECK (((liked IS NULL) = (vote_is_upvote IS NULL)));
|
||||
|
||||
-- Create new indexes, with `OR` being used to allow `IS NOT NULL` filters in queries to use either column in
|
||||
-- a group (e.g. `liked IS NOT NULL` and `like_score IS NOT NULL` both work)
|
||||
-- a group (e.g. `liked IS NOT NULL` and `vote_is_upvote IS NOT NULL` both work)
|
||||
CREATE INDEX idx_comment_actions_person ON comment_actions (person_id);
|
||||
|
||||
CREATE INDEX idx_comment_actions_comment ON comment_actions (comment_id);
|
||||
|
||||
CREATE INDEX idx_comment_actions_liked_not_null ON comment_actions (person_id, comment_id)
|
||||
WHERE
|
||||
liked IS NOT NULL OR like_score IS NOT NULL;
|
||||
liked IS NOT NULL OR vote_is_upvote IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_comment_actions_saved_not_null ON comment_actions (person_id, comment_id)
|
||||
WHERE
|
||||
@@ -63,15 +63,15 @@ WHERE
|
||||
-- SO link on merges: https://stackoverflow.com/a/74066614/1655478
|
||||
CREATE TABLE post_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
post_id,
|
||||
max(read) AS read,
|
||||
max(read_comments) AS read_comments,
|
||||
cast(max(read_comments_amount) AS int) AS read_comments_amount,
|
||||
max(saved) AS saved,
|
||||
max(liked) AS liked,
|
||||
cast(max(like_score) AS smallint) AS like_score,
|
||||
max(hidden) AS hidden
|
||||
max(hidden) AS hidden,
|
||||
person_id,
|
||||
post_id,
|
||||
cast(max(read_comments_amount) AS int) AS read_comments_amount,
|
||||
max(like_score) = 1 AS vote_is_upvote -- `null = 1` returns null
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
@@ -151,7 +151,7 @@ ALTER TABLE post_actions
|
||||
ADD PRIMARY KEY (person_id, post_id),
|
||||
ADD CONSTRAINT post_actions_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT post_actions_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT post_actions_check_liked CHECK (((liked IS NULL) = (like_score IS NULL))),
|
||||
ADD CONSTRAINT post_actions_check_liked CHECK (((liked IS NULL) = (vote_is_upvote IS NULL))),
|
||||
ADD CONSTRAINT post_actions_check_read_comments CHECK (((read_comments IS NULL) = (read_comments_amount IS NULL)));
|
||||
|
||||
-- Create indexes
|
||||
@@ -173,7 +173,7 @@ WHERE
|
||||
|
||||
CREATE INDEX idx_post_actions_liked_not_null ON post_actions (person_id, post_id)
|
||||
WHERE
|
||||
liked IS NOT NULL OR like_score IS NOT NULL;
|
||||
liked IS NOT NULL OR vote_is_upvote IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_post_actions_hidden_not_null ON post_actions (person_id, post_id)
|
||||
WHERE
|
||||
@@ -182,15 +182,15 @@ WHERE
|
||||
-- community_actions
|
||||
CREATE TABLE community_actions AS
|
||||
SELECT
|
||||
person_id,
|
||||
community_id,
|
||||
max(followed) AS followed,
|
||||
max(follow_state) AS follow_state,
|
||||
max(follow_approver_id) AS follow_approver_id,
|
||||
max(blocked) AS blocked,
|
||||
max(became_moderator) AS became_moderator,
|
||||
max(received_ban) AS received_ban,
|
||||
max(ban_expires) AS ban_expires
|
||||
max(ban_expires) AS ban_expires,
|
||||
person_id,
|
||||
community_id,
|
||||
max(follow_state) AS follow_state,
|
||||
max(follow_approver_id) AS follow_approver_id
|
||||
FROM (
|
||||
SELECT
|
||||
person_id,
|
||||
@@ -293,9 +293,9 @@ WHERE
|
||||
-- instance_actions
|
||||
CREATE TABLE instance_actions AS
|
||||
SELECT
|
||||
published AS blocked,
|
||||
person_id,
|
||||
instance_id,
|
||||
published AS blocked
|
||||
instance_id
|
||||
FROM
|
||||
instance_block;
|
||||
|
||||
@@ -322,11 +322,11 @@ WHERE
|
||||
-- person_actions
|
||||
CREATE TABLE person_actions AS
|
||||
SELECT
|
||||
max(followed) AS followed,
|
||||
max(blocked) AS blocked,
|
||||
person_id,
|
||||
target_id,
|
||||
max(followed) AS followed,
|
||||
cast(max(follow_pending) AS boolean) AS follow_pending,
|
||||
max(blocked) AS blocked
|
||||
cast(max(follow_pending) AS boolean) AS follow_pending
|
||||
FROM (
|
||||
SELECT
|
||||
follower_id AS person_id,
|
||||
@@ -376,7 +376,7 @@ WHERE
|
||||
-- `(liked, like_score)`, the query planner might othewise assume that `(TRUE, FALSE)` and `(TRUE, TRUE)`
|
||||
-- are equally likely when only `(TRUE, TRUE)` is possible, which would make it severely underestimate
|
||||
-- the efficiency of using the index)
|
||||
CREATE statistics comment_actions_liked_stat ON (liked IS NULL), (like_score IS NULL)
|
||||
CREATE statistics comment_actions_liked_stat ON (liked IS NULL), (vote_is_upvote IS NULL)
|
||||
FROM comment_actions;
|
||||
|
||||
CREATE statistics community_actions_followed_stat ON (followed IS NULL), (follow_state IS NULL)
|
||||
@@ -388,6 +388,6 @@ FROM person_actions;
|
||||
CREATE statistics post_actions_read_comments_stat ON (read_comments IS NULL), (read_comments_amount IS NULL)
|
||||
FROM post_actions;
|
||||
|
||||
CREATE statistics post_actions_liked_stat ON (liked IS NULL), (like_score IS NULL), (post_id IS NULL)
|
||||
CREATE statistics post_actions_liked_stat ON (liked IS NULL), (vote_is_upvote IS NULL), (post_id IS NULL)
|
||||
FROM post_actions;
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ SELECT
|
||||
upvotes,
|
||||
downvotes,
|
||||
published,
|
||||
newest_comment_time_necro,
|
||||
newest_comment_time,
|
||||
coalesce(newest_comment_time_necro, published),
|
||||
coalesce(newest_comment_time, published),
|
||||
featured_community,
|
||||
featured_local,
|
||||
hot_rank,
|
||||
@@ -102,7 +102,13 @@ SELECT
|
||||
community_id,
|
||||
creator_id,
|
||||
controversy_rank,
|
||||
instance_id,
|
||||
(
|
||||
SELECT
|
||||
community.instance_id
|
||||
FROM
|
||||
community
|
||||
WHERE
|
||||
community.id = post.community_id) AS instance_id,
|
||||
scaled_rank,
|
||||
report_count,
|
||||
unresolved_report_count
|
||||
@@ -139,7 +145,6 @@ ALTER TABLE post
|
||||
DROP COLUMN hot_rank,
|
||||
DROP COLUMN hot_rank_active,
|
||||
DROP COLUMN controversy_rank,
|
||||
DROP COLUMN instance_id,
|
||||
DROP COLUMN scaled_rank,
|
||||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count;
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
-- Merge comment_aggregates into comment table
|
||||
ALTER TABLE comment
|
||||
ADD COLUMN score int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score int NOT NULL DEFAULT 1, -- Default value only for previous rows, to match the similar thing done with `upvotes`
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 1, -- Default value only for previous rows, so the update below can filter out more rows by using `upvotes != 1` instead of `upvotes != 0`
|
||||
ADD COLUMN downvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN child_count int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN controversy_rank double precision NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank real NOT NULL DEFAULT 0, -- Default value only for previous rows, so the update below can filter out more rows by using `hot_rank != 0` instead of `hot_rank != 0.0001`
|
||||
ADD COLUMN controversy_rank real NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Default values only for future rows
|
||||
ALTER TABLE comment
|
||||
ALTER COLUMN score SET DEFAULT 0,
|
||||
ALTER COLUMN upvotes SET DEFAULT 0,
|
||||
ALTER COLUMN hot_rank SET DEFAULT 0.0001;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE comment DISABLE TRIGGER ALL;
|
||||
|
||||
@@ -40,7 +46,14 @@ SET
|
||||
FROM
|
||||
comment_aggregates AS ca
|
||||
WHERE
|
||||
comment.id = ca.comment_id;
|
||||
comment.id = ca.comment_id
|
||||
-- If `(upvotes, downvotes) = (1, 0)`, then `(score, controversy_rank) = (1, 0)`, so it would be redundant to check `score` and `controversy_rank` in this filter.
|
||||
AND (ca.upvotes != 1
|
||||
OR ca.downvotes != 0
|
||||
OR ca.child_count != 0
|
||||
OR ca.hot_rank != 0
|
||||
OR ca.report_count != 0
|
||||
OR ca.unresolved_report_count != 0);
|
||||
|
||||
DROP TABLE comment_aggregates;
|
||||
|
||||
@@ -77,20 +90,27 @@ CREATE INDEX idx_comment_score ON comment USING btree (score DESC);
|
||||
|
||||
-- merge post_aggregates into post table
|
||||
ALTER TABLE post
|
||||
ADD COLUMN newest_comment_time_necro timestamp with time zone,
|
||||
ADD COLUMN newest_comment_time timestamp with time zone,
|
||||
ADD COLUMN comments int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN score int NOT NULL DEFAULT 1, -- Default value only for previous rows, to match the similar thing done with `upvotes`
|
||||
ADD COLUMN upvotes int NOT NULL DEFAULT 1, -- Default value only for previous rows, so the update below can filter out more rows by using `upvotes != 1` instead of `upvotes != 0`
|
||||
ADD COLUMN downvotes int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN newest_comment_time_necro timestamp with time zone NOT NULL DEFAULT now(),
|
||||
ADD COLUMN newest_comment_time timestamp with time zone NOT NULL DEFAULT now(),
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN hot_rank_active double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN controversy_rank double precision NOT NULL DEFAULT 0,
|
||||
ADD COLUMN instance_id int REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD COLUMN scaled_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN hot_rank real NOT NULL DEFAULT 0, -- Default value only for previous rows, so the update below can filter out more rows by using `hot_rank != 0` instead of `hot_rank != 0.0001`
|
||||
ADD COLUMN hot_rank_active real NOT NULL DEFAULT 0, -- Default value only for previous rows, so the update below can filter out more rows by using `hot_rank_active != 0` instead of `hot_rank_active != 0.0001`
|
||||
ADD COLUMN controversy_rank real NOT NULL DEFAULT 0,
|
||||
ADD COLUMN scaled_rank real NOT NULL DEFAULT 0, -- Default value only for previous rows, so the update below can filter out more rows by using `scaled_rank != 0` instead of `scaled_rank != 0.0001`
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Default values only for future rows
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN score SET DEFAULT 0,
|
||||
ALTER COLUMN upvotes SET DEFAULT 0,
|
||||
ALTER COLUMN hot_rank SET DEFAULT 0.0001,
|
||||
ALTER COLUMN hot_rank_active SET DEFAULT 0.0001,
|
||||
ALTER COLUMN scaled_rank SET DEFAULT 0.0001;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE post DISABLE TRIGGER ALL;
|
||||
|
||||
@@ -111,23 +131,33 @@ WHERE
|
||||
UPDATE
|
||||
post
|
||||
SET
|
||||
newest_comment_time_necro = nullif (pa.newest_comment_time_necro, pa.published),
|
||||
newest_comment_time = nullif (pa.newest_comment_time, pa.published),
|
||||
comments = pa.comments,
|
||||
score = pa.score,
|
||||
upvotes = pa.upvotes,
|
||||
downvotes = pa.downvotes,
|
||||
newest_comment_time_necro = pa.newest_comment_time_necro,
|
||||
newest_comment_time = pa.newest_comment_time,
|
||||
hot_rank = pa.hot_rank,
|
||||
hot_rank_active = pa.hot_rank_active,
|
||||
controversy_rank = pa.controversy_rank,
|
||||
instance_id = pa.instance_id,
|
||||
scaled_rank = pa.scaled_rank,
|
||||
report_count = pa.report_count,
|
||||
unresolved_report_count = pa.unresolved_report_count
|
||||
FROM
|
||||
post_aggregates AS pa
|
||||
WHERE
|
||||
post.id = pa.post_id;
|
||||
post.id = pa.post_id
|
||||
-- If `(upvotes, downvotes) = (1, 0)`, then `(score, controversy_rank) = (1, 0)`, so it would be redundant to check `score` and `controversy_rank` in this filter.
|
||||
AND (pa.newest_comment_time_necro != pa.published
|
||||
OR pa.newest_comment_time != pa.published
|
||||
OR pa.comments != 0
|
||||
OR pa.upvotes != 1
|
||||
OR pa.downvotes != 0
|
||||
OR pa.hot_rank != 0
|
||||
OR pa.hot_rank_active != 0
|
||||
OR pa.scaled_rank != 0
|
||||
OR pa.report_count != 0
|
||||
OR pa.unresolved_report_count != 0);
|
||||
|
||||
-- Delete that data
|
||||
DROP TABLE post_aggregates;
|
||||
@@ -160,9 +190,9 @@ CREATE INDEX idx_post_community_hot ON post USING btree (community_id, featured_
|
||||
|
||||
CREATE INDEX idx_post_community_most_comments ON post USING btree (community_id, featured_local DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_newest_comment_time ON post USING btree (community_id, featured_local DESC, newest_comment_time DESC, id DESC);
|
||||
CREATE INDEX idx_post_community_newest_comment_time ON post USING btree (community_id, featured_local DESC, coalesce(newest_comment_time, published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_newest_comment_time_necro ON post USING btree (community_id, featured_local DESC, newest_comment_time_necro DESC, id DESC);
|
||||
CREATE INDEX idx_post_community_newest_comment_time_necro ON post USING btree (community_id, featured_local DESC, coalesce(newest_comment_time_necro, published) DESC, id DESC);
|
||||
|
||||
-- INDEX idx_post_community_published ON post USING btree (community_id, featured_local DESC, published DESC);
|
||||
--CREATE INDEX idx_post_community_published_asc ON post USING btree (community_id, featured_local DESC, reverse_timestamp_sort (published) DESC);
|
||||
@@ -178,9 +208,9 @@ CREATE INDEX idx_post_featured_community_hot ON post USING btree (community_id,
|
||||
|
||||
CREATE INDEX idx_post_featured_community_most_comments ON post USING btree (community_id, featured_community DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time ON post USING btree (community_id, featured_community DESC, newest_comment_time DESC, id DESC);
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time ON post USING btree (community_id, featured_community DESC, coalesce(newest_comment_time, published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time_necr ON post USING btree (community_id, featured_community DESC, newest_comment_time_necro DESC, id DESC);
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time_necr ON post USING btree (community_id, featured_community DESC, coalesce(newest_comment_time_necro, published) DESC, id DESC);
|
||||
|
||||
--CREATE INDEX idx_post_featured_community_published ON post USING btree (community_id, featured_community DESC, published DESC);
|
||||
CREATE INDEX idx_post_featured_community_published_asc ON post USING btree (community_id, featured_community DESC, reverse_timestamp_sort (published) DESC, id DESC);
|
||||
@@ -197,9 +227,9 @@ CREATE INDEX idx_post_featured_local_hot ON post USING btree (featured_local DES
|
||||
|
||||
CREATE INDEX idx_post_featured_local_most_comments ON post USING btree (featured_local DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time ON post USING btree (featured_local DESC, newest_comment_time DESC, id DESC);
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time ON post USING btree (featured_local DESC, coalesce(newest_comment_time, published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time_necro ON post USING btree (featured_local DESC, newest_comment_time_necro DESC, id DESC);
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time_necro ON post USING btree (featured_local DESC, coalesce(newest_comment_time_necro, published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_published ON post USING btree (featured_local DESC, published DESC, id DESC);
|
||||
|
||||
@@ -216,18 +246,23 @@ CREATE INDEX idx_post_published_asc ON post USING btree (reverse_timestamp_sort
|
||||
|
||||
-- merge community_aggregates into community table
|
||||
ALTER TABLE community
|
||||
ADD COLUMN subscribers int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN subscribers int NOT NULL DEFAULT 1, -- Default value only for previous rows, so the update below can filter out more rows by using `subscribers != 1` instead of `subscribers != 0`
|
||||
ADD COLUMN posts int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN hot_rank real NOT NULL DEFAULT 0, -- Default value only for previous rows, so the update below can filter out more rows by using `hot_rank != 0` instead of `hot_rank != 0.0001`
|
||||
ADD COLUMN subscribers_local int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month int NOT NULL DEFAULT 0;
|
||||
ADD COLUMN unresolved_report_count smallint NOT NULL DEFAULT 0;
|
||||
|
||||
-- Default values only for future rows
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN subscribers SET DEFAULT 0,
|
||||
ALTER COLUMN hot_rank SET DEFAULT 0.0001;
|
||||
|
||||
-- Disable the triggers temporarily
|
||||
ALTER TABLE community DISABLE TRIGGER ALL;
|
||||
@@ -258,13 +293,25 @@ SET
|
||||
users_active_half_year = ca.users_active_half_year,
|
||||
hot_rank = ca.hot_rank,
|
||||
subscribers_local = ca.subscribers_local,
|
||||
interactions_month = ca.interactions_month,
|
||||
report_count = ca.report_count,
|
||||
unresolved_report_count = ca.unresolved_report_count,
|
||||
interactions_month = ca.interactions_month
|
||||
unresolved_report_count = ca.unresolved_report_count
|
||||
FROM
|
||||
community_aggregates AS ca
|
||||
WHERE
|
||||
community.id = ca.community_id;
|
||||
community.id = ca.community_id
|
||||
AND (ca.subscribers != 1
|
||||
OR ca.posts != 0
|
||||
OR ca.comments != 0
|
||||
OR ca.users_active_day != 0
|
||||
OR ca.users_active_week != 0
|
||||
OR ca.users_active_month != 0
|
||||
OR ca.users_active_half_year != 0
|
||||
OR ca.hot_rank != 0
|
||||
OR ca.subscribers_local != 0
|
||||
OR ca.interactions_month != 0
|
||||
OR ca.report_count != 0
|
||||
OR ca.unresolved_report_count != 0);
|
||||
|
||||
DROP TABLE community_aggregates;
|
||||
|
||||
@@ -290,7 +337,7 @@ REINDEX TABLE community;
|
||||
|
||||
CREATE INDEX idx_community_hot ON public.community USING btree (hot_rank DESC);
|
||||
|
||||
CREATE INDEX idx_community_nonzero_hotrank ON public.community USING btree (published)
|
||||
CREATE INDEX idx_community_nonzero_hotrank ON community USING btree (published)
|
||||
WHERE (hot_rank <> (0)::double precision);
|
||||
|
||||
CREATE INDEX idx_community_subscribers ON public.community USING btree (subscribers DESC);
|
||||
@@ -331,7 +378,11 @@ SET
|
||||
FROM
|
||||
person_aggregates AS pa
|
||||
WHERE
|
||||
person.id = pa.person_id;
|
||||
person.id = pa.person_id
|
||||
AND (pa.post_count != 0
|
||||
OR pa.post_score != 0
|
||||
OR pa.comment_count != 0
|
||||
OR pa.comment_score != 0);
|
||||
|
||||
DROP TABLE person_aggregates;
|
||||
|
||||
@@ -455,7 +506,11 @@ SET
|
||||
FROM
|
||||
local_user_vote_display_mode AS v
|
||||
WHERE
|
||||
local_user.id = v.local_user_id;
|
||||
local_user.id = v.local_user_id
|
||||
AND (v.score
|
||||
OR NOT v.upvotes
|
||||
OR NOT v.downvotes
|
||||
OR v.upvote_percentage);
|
||||
|
||||
DROP TABLE local_user_vote_display_mode;
|
||||
|
||||
|
||||
@@ -1,132 +1,18 @@
|
||||
-- recreate columns in the original order
|
||||
ALTER TABLE community
|
||||
ADD COLUMN hidden bool DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN posting_restricted_to_mods_new bool NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN instance_id_new int,
|
||||
ADD COLUMN moderators_url_new varchar(255),
|
||||
ADD COLUMN featured_url_new varchar(255),
|
||||
ADD COLUMN visibility_new community_visibility NOT NULL DEFAULT 'Public',
|
||||
ADD COLUMN description_new varchar(150),
|
||||
ADD COLUMN random_number_new smallint NOT NULL DEFAULT random_smallint (),
|
||||
ADD COLUMN subscribers_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank_new double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN subscribers_local_new int NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month_new int NOT NULL DEFAULT 0;
|
||||
ADD COLUMN visibility_new community_visibility NOT NULL DEFAULT 'Public';
|
||||
|
||||
UPDATE
|
||||
community
|
||||
SET
|
||||
(posting_restricted_to_mods_new,
|
||||
instance_id_new,
|
||||
moderators_url_new,
|
||||
featured_url_new,
|
||||
visibility_new,
|
||||
description_new,
|
||||
random_number_new,
|
||||
subscribers_new,
|
||||
posts_new,
|
||||
comments_new,
|
||||
users_active_day_new,
|
||||
users_active_week_new,
|
||||
users_active_month_new,
|
||||
users_active_half_year_new,
|
||||
hot_rank_new,
|
||||
subscribers_local_new,
|
||||
report_count_new,
|
||||
unresolved_report_count_new,
|
||||
interactions_month_new) = (posting_restricted_to_mods,
|
||||
instance_id,
|
||||
moderators_url,
|
||||
featured_url,
|
||||
visibility,
|
||||
description,
|
||||
random_number,
|
||||
subscribers,
|
||||
posts,
|
||||
comments,
|
||||
users_active_day,
|
||||
users_active_week,
|
||||
users_active_month,
|
||||
users_active_half_year,
|
||||
hot_rank,
|
||||
subscribers_local,
|
||||
report_count,
|
||||
unresolved_report_count,
|
||||
interactions_month);
|
||||
visibility_new = visibility;
|
||||
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN instance_id_new SET NOT NULL,
|
||||
DROP COLUMN posting_restricted_to_mods,
|
||||
DROP COLUMN instance_id,
|
||||
DROP COLUMN moderators_url,
|
||||
DROP COLUMN featured_url,
|
||||
DROP COLUMN visibility,
|
||||
DROP COLUMN description,
|
||||
DROP COLUMN random_number,
|
||||
DROP COLUMN subscribers,
|
||||
DROP COLUMN posts,
|
||||
DROP COLUMN comments,
|
||||
DROP COLUMN users_active_day,
|
||||
DROP COLUMN users_active_week,
|
||||
DROP COLUMN users_active_month,
|
||||
DROP COLUMN users_active_half_year,
|
||||
DROP COLUMN hot_rank,
|
||||
DROP COLUMN subscribers_local,
|
||||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count,
|
||||
DROP COLUMN interactions_month;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN posting_restricted_to_mods_new TO posting_restricted_to_mods;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN instance_id_new TO instance_id;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN moderators_url_new TO moderators_url;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN featured_url_new TO featured_url;
|
||||
DROP COLUMN visibility;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN visibility_new TO visibility;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN description_new TO description;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN random_number_new TO random_number;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN subscribers_new TO subscribers;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN posts_new TO posts;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN comments_new TO comments;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_day_new TO users_active_day;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_week_new TO users_active_week;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_month_new TO users_active_month;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_half_year_new TO users_active_half_year;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN hot_rank_new TO hot_rank;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN subscribers_local_new TO subscribers_local;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN report_count_new TO report_count;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN unresolved_report_count_new TO unresolved_report_count;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN interactions_month_new TO interactions_month;
|
||||
|
||||
ALTER TABLE community
|
||||
ADD CONSTRAINT community_featured_url_key UNIQUE (featured_url),
|
||||
ADD CONSTRAINT community_moderators_url_key UNIQUE (moderators_url),
|
||||
ADD CONSTRAINT community_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
-- same changes as up.sql, but the other way round
|
||||
UPDATE
|
||||
community
|
||||
@@ -161,15 +47,6 @@ CREATE INDEX idx_community_random_number ON community (random_number) INCLUDE (l
|
||||
WHERE
|
||||
NOT (deleted OR removed OR visibility = 'Private');
|
||||
|
||||
CREATE INDEX idx_community_nonzero_hotrank ON community USING btree (published)
|
||||
WHERE (hot_rank <> (0)::double precision);
|
||||
|
||||
CREATE INDEX idx_community_subscribers ON community USING btree (subscribers DESC);
|
||||
|
||||
CREATE INDEX idx_community_users_active_month ON community USING btree (users_active_month DESC);
|
||||
|
||||
CREATE INDEX idx_community_hot ON public.community USING btree (hot_rank DESC);
|
||||
|
||||
REINDEX TABLE community;
|
||||
|
||||
-- revert modlog table changes
|
||||
|
||||
@@ -17,11 +17,7 @@ ALTER TABLE person
|
||||
ADD COLUMN matrix_user_id_new text,
|
||||
ADD COLUMN bot_account_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN ban_expires timestamptz,
|
||||
ADD COLUMN instance_id_new int,
|
||||
ADD COLUMN post_count_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN post_score_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_count_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN comment_score_new int DEFAULT 0 NOT NULL;
|
||||
ADD COLUMN instance_id_new int;
|
||||
|
||||
UPDATE
|
||||
person
|
||||
@@ -39,11 +35,7 @@ SET
|
||||
inbox_url_new,
|
||||
matrix_user_id_new,
|
||||
bot_account_new,
|
||||
instance_id_new,
|
||||
post_count_new,
|
||||
post_score_new,
|
||||
comment_count_new,
|
||||
comment_score_new) = (published,
|
||||
instance_id_new) = (published,
|
||||
updated,
|
||||
ap_id,
|
||||
bio,
|
||||
@@ -56,11 +48,7 @@ SET
|
||||
inbox_url,
|
||||
matrix_user_id,
|
||||
bot_account,
|
||||
instance_id,
|
||||
post_count,
|
||||
post_score,
|
||||
comment_count,
|
||||
comment_score);
|
||||
instance_id);
|
||||
|
||||
ALTER TABLE person
|
||||
DROP COLUMN published,
|
||||
@@ -76,11 +64,7 @@ ALTER TABLE person
|
||||
DROP COLUMN inbox_url,
|
||||
DROP COLUMN matrix_user_id,
|
||||
DROP COLUMN bot_account,
|
||||
DROP COLUMN instance_id,
|
||||
DROP COLUMN post_count,
|
||||
DROP COLUMN post_score,
|
||||
DROP COLUMN comment_count,
|
||||
DROP COLUMN comment_score;
|
||||
DROP COLUMN instance_id;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN published_new TO published;
|
||||
|
||||
@@ -110,14 +94,6 @@ ALTER TABLE person RENAME COLUMN bot_account_new TO bot_account;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN instance_id_new TO instance_id;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN post_count_new TO post_count;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN post_score_new TO post_score;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN comment_count_new TO comment_count;
|
||||
|
||||
ALTER TABLE person RENAME COLUMN comment_score_new TO comment_score;
|
||||
|
||||
ALTER TABLE person
|
||||
ALTER public_key SET NOT NULL,
|
||||
ALTER instance_id SET NOT NULL,
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
ALTER TABLE post
|
||||
ADD COLUMN name_new character varying(200),
|
||||
ADD COLUMN url_new character varying(2000),
|
||||
ADD COLUMN body_new text,
|
||||
ADD COLUMN creator_id_new integer,
|
||||
ADD COLUMN community_id_new integer,
|
||||
ADD COLUMN removed_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN locked_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN published_new timestamp with time zone DEFAULT now() NOT NULL,
|
||||
ADD COLUMN updated_new timestamp with time zone,
|
||||
ADD COLUMN deleted_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN nsfw_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN embed_title_new text,
|
||||
ADD COLUMN embed_description_new text,
|
||||
ADD COLUMN thumbnail_url_new text,
|
||||
ADD COLUMN ap_id_new character varying(255),
|
||||
ADD COLUMN local_new boolean DEFAULT TRUE NOT NULL,
|
||||
ADD COLUMN embed_video_url_new text,
|
||||
ADD COLUMN language_id_new integer DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN featured_community_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN featured_local_new boolean DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN url_content_type_new text,
|
||||
ADD COLUMN alt_text_new text,
|
||||
ADD COLUMN scheduled_publish_time_new timestamp with time zone,
|
||||
ADD COLUMN comments_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN score_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN upvotes_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN downvotes_new int DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN newest_comment_time_necro_new timestamp with time zone DEFAULT now() NOT NULL,
|
||||
ADD COLUMN newest_comment_time_new timestamp with time zone DEFAULT now() NOT NULL,
|
||||
ADD COLUMN hot_rank_new double precision DEFAULT 0.0001 NOT NULL,
|
||||
ADD COLUMN hot_rank_active_new double precision DEFAULT 0.0001 NOT NULL,
|
||||
ADD COLUMN controversy_rank_new double precision DEFAULT 0 NOT NULL,
|
||||
-- Old column here
|
||||
ADD COLUMN instance_id integer,
|
||||
ADD COLUMN scaled_rank_new double precision DEFAULT 0.0001 NOT NULL,
|
||||
ADD COLUMN report_count_new smallint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN unresolved_report_count_new smallint DEFAULT 0 NOT NULL,
|
||||
ADD COLUMN federation_pending_new boolean DEFAULT FALSE NOT NULL;
|
||||
|
||||
UPDATE
|
||||
post
|
||||
SET
|
||||
(instance_id,
|
||||
name_new,
|
||||
url_new,
|
||||
body_new,
|
||||
creator_id_new,
|
||||
community_id_new,
|
||||
removed_new,
|
||||
locked_new,
|
||||
published_new,
|
||||
updated_new,
|
||||
deleted_new,
|
||||
nsfw_new,
|
||||
embed_title_new,
|
||||
embed_description_new,
|
||||
thumbnail_url_new,
|
||||
ap_id_new,
|
||||
local_new,
|
||||
embed_video_url_new,
|
||||
language_id_new,
|
||||
featured_community_new,
|
||||
featured_local_new,
|
||||
url_content_type_new,
|
||||
alt_text_new,
|
||||
scheduled_publish_time_new,
|
||||
comments_new,
|
||||
score_new,
|
||||
upvotes_new,
|
||||
downvotes_new,
|
||||
newest_comment_time_necro_new,
|
||||
newest_comment_time_new,
|
||||
hot_rank_new,
|
||||
hot_rank_active_new,
|
||||
controversy_rank_new,
|
||||
scaled_rank_new,
|
||||
report_count_new,
|
||||
unresolved_report_count_new,
|
||||
federation_pending_new) = (0,
|
||||
name,
|
||||
url,
|
||||
body,
|
||||
creator_id,
|
||||
community_id,
|
||||
removed,
|
||||
LOCKED,
|
||||
published,
|
||||
updated,
|
||||
deleted,
|
||||
nsfw,
|
||||
embed_title,
|
||||
embed_description,
|
||||
thumbnail_url,
|
||||
ap_id,
|
||||
local,
|
||||
embed_video_url,
|
||||
language_id,
|
||||
featured_community,
|
||||
featured_local,
|
||||
url_content_type,
|
||||
alt_text,
|
||||
scheduled_publish_time,
|
||||
comments,
|
||||
score,
|
||||
upvotes,
|
||||
downvotes,
|
||||
newest_comment_time_necro,
|
||||
newest_comment_time,
|
||||
hot_rank,
|
||||
hot_rank_active,
|
||||
controversy_rank,
|
||||
scaled_rank,
|
||||
report_count,
|
||||
unresolved_report_count,
|
||||
federation_pending);
|
||||
|
||||
ALTER TABLE post
|
||||
DROP COLUMN name,
|
||||
DROP COLUMN url,
|
||||
DROP COLUMN body,
|
||||
DROP COLUMN creator_id,
|
||||
DROP COLUMN community_id,
|
||||
DROP COLUMN removed,
|
||||
DROP COLUMN LOCKED,
|
||||
DROP COLUMN published,
|
||||
DROP COLUMN updated,
|
||||
DROP COLUMN deleted,
|
||||
DROP COLUMN nsfw,
|
||||
DROP COLUMN embed_title,
|
||||
DROP COLUMN embed_description,
|
||||
DROP COLUMN thumbnail_url,
|
||||
DROP COLUMN ap_id,
|
||||
DROP COLUMN local,
|
||||
DROP COLUMN embed_video_url,
|
||||
DROP COLUMN language_id,
|
||||
DROP COLUMN featured_community,
|
||||
DROP COLUMN featured_local,
|
||||
DROP COLUMN url_content_type,
|
||||
DROP COLUMN alt_text,
|
||||
DROP COLUMN scheduled_publish_time,
|
||||
DROP COLUMN comments,
|
||||
DROP COLUMN score,
|
||||
DROP COLUMN upvotes,
|
||||
DROP COLUMN downvotes,
|
||||
DROP COLUMN newest_comment_time_necro,
|
||||
DROP COLUMN newest_comment_time,
|
||||
DROP COLUMN hot_rank,
|
||||
DROP COLUMN hot_rank_active,
|
||||
DROP COLUMN controversy_rank,
|
||||
DROP COLUMN scaled_rank,
|
||||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count,
|
||||
DROP COLUMN federation_pending;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN name_new TO name;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN url_new TO url;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN body_new TO body;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN creator_id_new TO creator_id;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN community_id_new TO community_id;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN removed_new TO removed;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN locked_new TO LOCKED;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN published_new TO published;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN updated_new TO updated;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN deleted_new TO deleted;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN nsfw_new TO nsfw;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN embed_title_new TO embed_title;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN embed_description_new TO embed_description;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN thumbnail_url_new TO thumbnail_url;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN ap_id_new TO ap_id;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN local_new TO local;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN embed_video_url_new TO embed_video_url;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN language_id_new TO language_id;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN featured_community_new TO featured_community;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN featured_local_new TO featured_local;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN url_content_type_new TO url_content_type;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN alt_text_new TO alt_text;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN scheduled_publish_time_new TO scheduled_publish_time;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN comments_new TO comments;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN score_new TO score;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN upvotes_new TO upvotes;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN downvotes_new TO downvotes;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN newest_comment_time_necro_new TO newest_comment_time_necro;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN newest_comment_time_new TO newest_comment_time;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN hot_rank_new TO hot_rank;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN hot_rank_active_new TO hot_rank_active;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN controversy_rank_new TO controversy_rank;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN scaled_rank_new TO scaled_rank;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN report_count_new TO report_count;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN unresolved_report_count_new TO unresolved_report_count;
|
||||
|
||||
ALTER TABLE post RENAME COLUMN federation_pending_new TO federation_pending;
|
||||
|
||||
-- Update the historical instance_id rows
|
||||
UPDATE
|
||||
post AS p
|
||||
SET
|
||||
instance_id = c.instance_id
|
||||
FROM
|
||||
community AS c
|
||||
WHERE
|
||||
p.community_id = c.id;
|
||||
|
||||
ALTER TABLE ONLY post
|
||||
ADD CONSTRAINT idx_post_ap_id UNIQUE (ap_id);
|
||||
|
||||
CREATE INDEX idx_post_community ON post USING btree (community_id);
|
||||
|
||||
CREATE INDEX idx_post_community_active ON post USING btree (community_id, featured_local DESC, hot_rank_active DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_controversy ON post USING btree (community_id, featured_local DESC, controversy_rank DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_hot ON post USING btree (community_id, featured_local DESC, hot_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_most_comments ON post USING btree (community_id, featured_local DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_newest_comment_time ON post USING btree (community_id, featured_local DESC, newest_comment_time DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_newest_comment_time_necro ON post USING btree (community_id, featured_local DESC, newest_comment_time_necro DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_scaled ON post USING btree (community_id, featured_local DESC, scaled_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_community_score ON post USING btree (community_id, featured_local DESC, score DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_creator ON post USING btree (creator_id);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_active ON post USING btree (community_id, featured_community DESC, hot_rank_active DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_controversy ON post USING btree (community_id, featured_community DESC, controversy_rank DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_hot ON post USING btree (community_id, featured_community DESC, hot_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_most_comments ON post USING btree (community_id, featured_community DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time ON post USING btree (community_id, featured_community DESC, newest_comment_time DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_newest_comment_time_necr ON post USING btree (community_id, featured_community DESC, newest_comment_time_necro DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_published_asc ON post USING btree (community_id, featured_community DESC, reverse_timestamp_sort (published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_scaled ON post USING btree (community_id, featured_community DESC, scaled_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_community_score ON post USING btree (community_id, featured_community DESC, score DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_active ON post USING btree (featured_local DESC, hot_rank_active DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_controversy ON post USING btree (featured_local DESC, controversy_rank DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_hot ON post USING btree (featured_local DESC, hot_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_most_comments ON post USING btree (featured_local DESC, comments DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time ON post USING btree (featured_local DESC, newest_comment_time DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_newest_comment_time_necro ON post USING btree (featured_local DESC, newest_comment_time_necro DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_published ON post USING btree (featured_local DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_published_asc ON post USING btree (featured_local DESC, reverse_timestamp_sort (published) DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_scaled ON post USING btree (featured_local DESC, scaled_rank DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_featured_local_score ON post USING btree (featured_local DESC, score DESC, published DESC, id DESC);
|
||||
|
||||
CREATE INDEX idx_post_language ON post USING btree (language_id);
|
||||
|
||||
CREATE INDEX idx_post_nonzero_hotrank ON post USING btree (published DESC)
|
||||
WHERE ((hot_rank <> (0)::double precision) OR (hot_rank_active <> (0)::double precision));
|
||||
|
||||
CREATE INDEX idx_post_published ON post USING btree (published);
|
||||
|
||||
CREATE INDEX idx_post_published_asc ON post USING btree (reverse_timestamp_sort (published) DESC);
|
||||
|
||||
CREATE INDEX idx_post_scheduled_publish_time ON post USING btree (scheduled_publish_time);
|
||||
|
||||
CREATE INDEX idx_post_trigram ON post USING gin (name gin_trgm_ops, body gin_trgm_ops, alt_text gin_trgm_ops);
|
||||
|
||||
CREATE INDEX idx_post_url ON post USING btree (url);
|
||||
|
||||
CREATE INDEX idx_post_url_content_type ON post USING gin (url_content_type gin_trgm_ops);
|
||||
|
||||
ALTER TABLE ONLY post
|
||||
ADD CONSTRAINT post_community_id_fkey FOREIGN KEY (community_id) REFERENCES community (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY post
|
||||
ADD CONSTRAINT post_creator_id_fkey FOREIGN KEY (creator_id) REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY post
|
||||
ADD CONSTRAINT post_language_id_fkey FOREIGN KEY (language_id) REFERENCES LANGUAGE (id);
|
||||
|
||||
ALTER TABLE ONLY post
|
||||
ADD CONSTRAINT post_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN name SET NOT NULL;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN creator_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN community_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE post
|
||||
ALTER COLUMN ap_id SET NOT NULL;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE post
|
||||
DROP COLUMN instance_id;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
CREATE INDEX idx_tagline_published_id ON tagline (published DESC, id DESC);
|
||||
|
||||
-- Some for the vote views
|
||||
CREATE INDEX idx_comment_actions_like_score ON comment_actions (comment_id, like_score, person_id)
|
||||
CREATE INDEX idx_comment_actions_like_score ON comment_actions (comment_id, vote_is_upvote, person_id)
|
||||
WHERE
|
||||
like_score IS NOT NULL;
|
||||
vote_is_upvote IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_post_actions_like_score ON post_actions (post_id, like_score, person_id)
|
||||
CREATE INDEX idx_post_actions_like_score ON post_actions (post_id, vote_is_upvote, person_id)
|
||||
WHERE
|
||||
like_score IS NOT NULL;
|
||||
vote_is_upvote IS NOT NULL;
|
||||
|
||||
-- Fixing the community sorts for an id tie-breaker
|
||||
DROP INDEX idx_community_lower_name;
|
||||
|
||||
@@ -2,13 +2,22 @@
|
||||
-- person_liked: (comment, post)
|
||||
-- This one is special, because you use the liked date, not the ordinary published
|
||||
-- Updating the history
|
||||
CREATE SEQUENCE person_liked_combined_id_seq
|
||||
AS integer START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE person_liked_combined AS
|
||||
SELECT
|
||||
pa.liked,
|
||||
pa.like_score,
|
||||
-- `ADD COLUMN id serial` is not used for this because it would require either putting the column at the end (might increase the amount of padding bytes) or using an `INSERT` statement (not parallelizable).
|
||||
nextval('person_liked_combined_id_seq'::regclass)::int AS id,
|
||||
pa.person_id,
|
||||
pa.post_id,
|
||||
NULL::int AS comment_id
|
||||
NULL::int AS comment_id,
|
||||
pa.vote_is_upvote
|
||||
FROM
|
||||
post_actions pa
|
||||
INNER JOIN person p ON pa.person_id = p.id
|
||||
@@ -18,10 +27,11 @@ WHERE
|
||||
UNION ALL
|
||||
SELECT
|
||||
ca.liked,
|
||||
ca.like_score,
|
||||
nextval('person_liked_combined_id_seq'::regclass)::int,
|
||||
ca.person_id,
|
||||
NULL::int,
|
||||
ca.comment_id
|
||||
ca.comment_id,
|
||||
ca.vote_is_upvote
|
||||
FROM
|
||||
comment_actions ca
|
||||
INNER JOIN person p ON ca.person_id = p.id
|
||||
@@ -30,16 +40,19 @@ WHERE
|
||||
AND p.local = TRUE;
|
||||
|
||||
ALTER TABLE person_liked_combined
|
||||
ADD COLUMN id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
ALTER COLUMN id SET DEFAULT nextval('person_liked_combined_id_seq'::regclass),
|
||||
ALTER COLUMN liked SET NOT NULL,
|
||||
ALTER COLUMN like_score SET NOT NULL,
|
||||
ALTER COLUMN vote_is_upvote SET NOT NULL,
|
||||
ALTER COLUMN person_id SET NOT NULL,
|
||||
ADD CONSTRAINT person_liked_combined_person_id_fkey FOREIGN KEY (person_id) REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_liked_combined_post_id_fkey FOREIGN KEY (post_id) REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT person_liked_combined_comment_id_fkey FOREIGN KEY (comment_id) REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD UNIQUE (person_id, post_id),
|
||||
ADD UNIQUE (person_id, comment_id),
|
||||
ADD PRIMARY KEY (id),
|
||||
ADD CONSTRAINT person_liked_combined_check CHECK (num_nonnulls (post_id, comment_id) = 1);
|
||||
|
||||
ALTER SEQUENCE person_liked_combined_id_seq OWNED BY person_liked_combined.id;
|
||||
|
||||
CREATE INDEX idx_person_liked_combined ON person_liked_combined (person_id);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ ALTER TABLE comment RENAME COLUMN published_at TO published;
|
||||
|
||||
ALTER TABLE comment RENAME COLUMN updated_at TO updated;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN liked_at TO liked;
|
||||
ALTER TABLE comment_actions RENAME COLUMN voted_at TO liked;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN saved_at TO saved;
|
||||
|
||||
@@ -148,7 +148,7 @@ ALTER TABLE person_comment_mention RENAME COLUMN published_at TO published;
|
||||
|
||||
ALTER TABLE person_content_combined RENAME COLUMN published_at TO published;
|
||||
|
||||
ALTER TABLE person_liked_combined RENAME COLUMN liked_at TO liked;
|
||||
ALTER TABLE person_liked_combined RENAME COLUMN voted_at TO liked;
|
||||
|
||||
ALTER TABLE person_post_mention RENAME COLUMN published_at TO published;
|
||||
|
||||
@@ -170,7 +170,7 @@ ALTER TABLE post_actions RENAME COLUMN read_comments_at TO read_comments;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN saved_at TO saved;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN liked_at TO liked;
|
||||
ALTER TABLE post_actions RENAME COLUMN voted_at TO liked;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN hidden_at TO hidden;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ ALTER TABLE comment RENAME COLUMN published TO published_at;
|
||||
|
||||
ALTER TABLE comment RENAME COLUMN updated TO updated_at;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN liked TO liked_at;
|
||||
ALTER TABLE comment_actions RENAME COLUMN liked TO voted_at;
|
||||
|
||||
ALTER TABLE comment_actions RENAME COLUMN saved TO saved_at;
|
||||
|
||||
@@ -148,7 +148,7 @@ ALTER TABLE person_comment_mention RENAME COLUMN published TO published_at;
|
||||
|
||||
ALTER TABLE person_content_combined RENAME COLUMN published TO published_at;
|
||||
|
||||
ALTER TABLE person_liked_combined RENAME COLUMN liked TO liked_at;
|
||||
ALTER TABLE person_liked_combined RENAME COLUMN liked TO voted_at;
|
||||
|
||||
ALTER TABLE person_post_mention RENAME COLUMN published TO published_at;
|
||||
|
||||
@@ -170,7 +170,7 @@ ALTER TABLE post_actions RENAME COLUMN read_comments TO read_comments_at;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN saved TO saved_at;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN liked TO liked_at;
|
||||
ALTER TABLE post_actions RENAME COLUMN liked TO voted_at;
|
||||
|
||||
ALTER TABLE post_actions RENAME COLUMN hidden TO hidden_at;
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ SELECT
|
||||
votes.person_id,
|
||||
votes.creator_id,
|
||||
now(),
|
||||
count(*) FILTER (WHERE votes.like_score = 1) AS upvotes,
|
||||
count(*) FILTER (WHERE votes.like_score != 1) AS downvotes
|
||||
count(*) FILTER (WHERE votes.vote_is_upvote) AS upvotes,
|
||||
count(*) FILTER (WHERE NOT votes.vote_is_upvote) AS downvotes
|
||||
FROM (
|
||||
SELECT
|
||||
pa.person_id,
|
||||
p.creator_id,
|
||||
like_score
|
||||
vote_is_upvote
|
||||
FROM
|
||||
post_actions pa
|
||||
INNER JOIN post p ON pa.post_id = p.id
|
||||
@@ -35,7 +35,7 @@ FROM (
|
||||
SELECT
|
||||
ca.person_id,
|
||||
c.creator_id,
|
||||
like_score
|
||||
vote_is_upvote
|
||||
FROM
|
||||
comment_actions ca
|
||||
INNER JOIN comment c ON ca.comment_id = c.id
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
DROP INDEX idx_post_actions_liked_at, idx_comment_actions_liked_at;
|
||||
DROP INDEX idx_post_actions_voted_at, idx_comment_actions_voted_at;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
CREATE INDEX idx_post_actions_liked_at ON post_actions (liked_at)
|
||||
CREATE INDEX idx_post_actions_voted_at ON post_actions (voted_at)
|
||||
WHERE
|
||||
liked_at IS NOT NULL;
|
||||
voted_at IS NOT NULL;
|
||||
|
||||
CREATE INDEX idx_comment_actions_liked_at ON comment_actions (liked_at)
|
||||
CREATE INDEX idx_comment_actions_voted_at ON comment_actions (voted_at)
|
||||
WHERE
|
||||
liked_at IS NOT NULL;
|
||||
voted_at IS NOT NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user