Adding person_local column to post_actions and comment_actions

This commit is contained in:
Dessalines 2025-05-01 14:56:24 -04:00
parent ba763c9b98
commit e5145d8b07
31 changed files with 263 additions and 186 deletions

View file

@ -68,7 +68,12 @@ pub async fn like_comment(
}
}
let mut like_form = CommentLikeForm::new(local_user_view.person.id, data.comment_id, data.score);
let mut like_form = CommentLikeForm::new(
local_user_view.person.id,
local_user_view.person.local,
data.comment_id,
data.score,
);
// Remove any likes first
let person_id = local_user_view.person.id;

View file

@ -16,7 +16,11 @@ pub async fn save_comment(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> {
let comment_saved_form = CommentSavedForm::new(local_user_view.person.id, data.comment_id);
let comment_saved_form = CommentSavedForm::new(
local_user_view.person.id,
local_user_view.person.local,
data.comment_id,
);
if data.save {
CommentActions::save(&mut context.pool(), &comment_saved_form).await?;

View file

@ -17,10 +17,12 @@ pub async fn hide_post(
local_user_view: LocalUserView,
) -> LemmyResult<Json<PostResponse>> {
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let local_instance_id = local_user_view.person.instance_id;
let post_id = data.post_id;
let hide_form = PostHideForm::new(post_id, person_id);
let hide_form = PostHideForm::new(post_id, person_id, person_local);
// Mark the post as hidden / unhidden
if data.hide {

View file

@ -26,6 +26,8 @@ pub async fn like_post(
) -> LemmyResult<Json<PostResponse>> {
let local_site = SiteView::read_local(&mut context.pool()).await?.local_site;
let local_instance_id = local_user_view.person.instance_id;
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let post_id = data.post_id;
check_local_vote_mode(
@ -43,11 +45,9 @@ pub async fn like_post(
check_community_user_action(&local_user_view, &post.community, &mut context.pool()).await?;
let mut like_form = PostLikeForm::new(data.post_id, local_user_view.person.id, data.score);
let mut like_form = PostLikeForm::new(data.post_id, person_id, person_local, data.score);
// Remove any likes first
let person_id = local_user_view.person.id;
PostActions::remove_like(&mut context.pool(), person_id, post_id).await?;
// Only add the like if the score isnt 0
@ -60,7 +60,7 @@ pub async fn like_post(
}
// Mark Post Read
let read_form = PostReadForm::new(post_id, person_id);
let read_form = PostReadForm::new(post_id, person_id, person_local);
PostActions::mark_as_read(&mut context.pool(), &read_form).await?;
ActivityChannel::submit_activity(

View file

@ -15,8 +15,9 @@ pub async fn mark_posts_as_read(
}
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let forms = PostActions::build_many_read_forms(post_ids, person_id);
let forms = PostActions::build_many_read_forms(post_ids, person_id, person_local);
// Mark the posts as read
PostActions::mark_many_as_read(&mut context.pool(), &forms).await?;

View file

@ -17,11 +17,12 @@ pub async fn mark_post_as_read(
local_user_view: LocalUserView,
) -> LemmyResult<Json<PostResponse>> {
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let local_instance_id = local_user_view.person.instance_id;
let post_id = data.post_id;
// Mark the post as read / unread
let form = PostReadForm::new(post_id, person_id);
let form = PostReadForm::new(post_id, person_id, person_local);
if data.read {
PostActions::mark_as_read(&mut context.pool(), &form).await?;
} else {

View file

@ -16,7 +16,11 @@ pub async fn save_post(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<PostResponse>> {
let post_saved_form = PostSavedForm::new(data.post_id, local_user_view.person.id);
let post_saved_form = PostSavedForm::new(
data.post_id,
local_user_view.person.id,
local_user_view.person.local,
);
if data.save {
PostActions::save(&mut context.pool(), &post_saved_form).await?;
@ -26,6 +30,7 @@ pub async fn save_post(
let post_id = data.post_id;
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let local_instance_id = local_user_view.person.instance_id;
let post_view = PostView::read(
&mut context.pool(),
@ -36,7 +41,7 @@ pub async fn save_post(
)
.await?;
let read_form = PostReadForm::new(post_id, person_id);
let read_form = PostReadForm::new(post_id, person_id, person_local);
PostActions::mark_as_read(&mut context.pool(), &read_form).await?;
Ok(Json(PostResponse { post_view }))

View file

@ -179,11 +179,13 @@ pub fn is_top_mod(
/// Updates the read comment count for a post. Usually done when reading or creating a new comment.
pub async fn update_read_comments(
person_id: PersonId,
person_local: bool,
post_id: PostId,
read_comments: i64,
pool: &mut DbPool<'_>,
) -> LemmyResult<()> {
let person_post_agg_form = PostReadCommentsForm::new(post_id, person_id, read_comments);
let person_post_agg_form =
PostReadCommentsForm::new(post_id, person_id, person_local, read_comments);
PostActions::update_read_comments(pool, &person_post_agg_form).await?;
Ok(())

View file

@ -130,7 +130,12 @@ pub async fn create_comment(
.await?;
// 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,
local_user_view.person.local,
inserted_comment.id,
1,
);
CommentActions::like(&mut context.pool(), &like_form).await?;
@ -142,6 +147,7 @@ pub async fn create_comment(
// Update the read comments, so your own new comment doesn't appear as a +1 unread
update_read_comments(
local_user_view.person.id,
local_user_view.person.local,
post_id,
post.comments + 1,
&mut context.pool(),

View file

@ -168,9 +168,10 @@ pub async fn create_post(
// They like their own post by default
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
let post_id = inserted_post.id;
let local_instance_id = local_user_view.person.instance_id;
let like_form = PostLikeForm::new(post_id, person_id, 1);
let like_form = PostLikeForm::new(post_id, person_id, person_local, 1);
PostActions::like(&mut context.pool(), &like_form).await?;
@ -188,7 +189,7 @@ pub async fn create_post(
)
.await?;
let read_form = PostReadForm::new(post_id, person_id);
let read_form = PostReadForm::new(post_id, person_id, person_local);
PostActions::mark_as_read(&mut context.pool(), &read_form).await?;
build_post_response(&context, community_id, local_user_view, post_id).await

View file

@ -30,7 +30,7 @@ pub async fn get_post(
check_private_instance(&local_user_view, &local_site)?;
let person_id = local_user_view.as_ref().map(|u| u.person.id);
let person = local_user_view.as_ref().map(|u| u.person.clone());
let local_user = local_user_view.as_ref().map(|l| l.local_user.clone());
// I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate
@ -66,12 +66,13 @@ pub async fn get_post(
.await?;
let post_id = post_view.post.id;
if let Some(person_id) = person_id {
let read_form = PostReadForm::new(post_id, person_id);
if let Some(person) = person {
let read_form = PostReadForm::new(post_id, person.id, person.local);
PostActions::mark_as_read(&mut context.pool(), &read_form).await?;
update_read_comments(
person_id,
person.id,
person.local,
post_id,
post_view.post.comments,
&mut context.pool(),

View file

@ -142,6 +142,8 @@ impl ActivityHandler for CreateOrUpdateNote {
// Need to do this check here instead of Note::from_json because we need the person who
// send the activity, not the comment author.
let existing_comment = self.object.id.dereference_local(context).await.ok();
let creator = self.actor.dereference(context).await?;
if let (Some(distinguished), Some(existing_comment)) =
(self.object.distinguished, existing_comment)
{
@ -161,7 +163,7 @@ impl ActivityHandler 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, creator.local, comment.id, 1);
CommentActions::like(&mut context.pool(), &like_form).await?;
// Calculate initial hot_rank
@ -169,7 +171,6 @@ impl ActivityHandler for CreateOrUpdateNote {
let do_send_email =
self.kind == CreateOrUpdateType::Create && !site_view.local_site.disable_email_notifications;
let actor = self.actor.dereference(context).await?;
// Note:
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
@ -183,7 +184,7 @@ impl ActivityHandler for CreateOrUpdateNote {
send_local_notifs(
mentions,
PostOrCommentId::Comment(comment.id),
&actor,
&creator,
do_send_email,
context,
None,

View file

@ -118,9 +118,10 @@ impl ActivityHandler for CreateOrUpdatePage {
insert_received_activity(&self.id, context).await?;
let post = ApubPost::from_json(self.object, context).await?;
let actor = self.actor.dereference(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, actor.local, 1);
PostActions::like(&mut context.pool(), &like_form).await?;
// Calculate initial hot_rank for post
@ -128,7 +129,6 @@ impl ActivityHandler for CreateOrUpdatePage {
let do_send_email =
self.kind == CreateOrUpdateType::Create && !site_view.local_site.disable_email_notifications;
let actor = self.actor.dereference(context).await?;
// Send the post body mentions
let mentions = scrape_text_for_mentions(&post.body.clone().unwrap_or_default());

View file

@ -62,7 +62,7 @@ async fn vote_comment(
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let comment_id = comment.id;
let mut like_form = CommentLikeForm::new(actor.id, comment_id, vote_type.into());
let mut like_form = CommentLikeForm::new(actor.id, actor.local, comment_id, vote_type.into());
let person_id = actor.id;
comment.set_not_pending(&mut context.pool()).await?;
CommentActions::remove_like(&mut context.pool(), person_id, comment_id).await?;
@ -79,7 +79,7 @@ async fn vote_post(
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let post_id = post.id;
let mut like_form = PostLikeForm::new(post.id, actor.id, vote_type.into());
let mut like_form = PostLikeForm::new(post.id, actor.id, actor.local, vote_type.into());
let person_id = actor.id;
post.set_not_pending(&mut context.pool()).await?;
PostActions::remove_like(&mut context.pool(), person_id, post_id).await?;

View file

@ -103,13 +103,17 @@ pub async fn list_posts(
.await?;
// If in their user settings (or as part of the API request), auto-mark fetched posts as read
if let Some(local_user) = local_user {
if let Some(local_user_view) = local_user_view {
if data
.mark_as_read
.unwrap_or(local_user.auto_mark_fetched_posts_as_read)
.unwrap_or(local_user_view.local_user.auto_mark_fetched_posts_as_read)
{
let post_ids = posts.iter().map(|p| p.post.id).collect::<Vec<PostId>>();
let forms = PostActions::build_many_read_forms(&post_ids, local_user.person_id);
let forms = PostActions::build_many_read_forms(
&post_ids,
local_user_view.person.id,
local_user_view.person.local,
);
PostActions::mark_many_as_read(&mut context.pool(), &forms).await?;
}
}

View file

@ -150,6 +150,7 @@ pub async fn import_settings(
spawn_try_task(async move {
let person_id = local_user_view.person.id;
let person_local = local_user_view.person.local;
info!(
"Starting settings import for {}",
@ -174,7 +175,7 @@ pub async fn import_settings(
&context,
|(saved, context)| async move {
let post = saved.dereference(&context).await?;
let form = PostSavedForm::new(post.id, person_id);
let form = PostSavedForm::new(post.id, person_id, person_local);
PostActions::save(&mut context.pool(), &form).await?;
LemmyResult::Ok(())
},
@ -186,7 +187,7 @@ pub async fn import_settings(
&context,
|(saved, context)| async move {
let comment = saved.dereference(&context).await?;
let form = CommentSavedForm::new(person_id, comment.id);
let form = CommentSavedForm::new(person_id, person_local, comment.id);
CommentActions::save(&mut context.pool(), &form).await?;
LemmyResult::Ok(())
},

View file

@ -408,13 +408,22 @@ 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_person.local,
inserted_comment.id,
1,
);
let inserted_comment_like = CommentActions::like(pool, &comment_like_form).await?;
assert_eq!(Some(1), inserted_comment_like.like_score);
// Comment Saved
let comment_saved_form = CommentSavedForm::new(inserted_person.id, inserted_comment.id);
let comment_saved_form = CommentSavedForm::new(
inserted_person.id,
inserted_person.local,
inserted_comment.id,
);
let inserted_comment_saved = CommentActions::save(pool, &comment_saved_form).await?;
assert!(inserted_comment_saved.saved.is_some());
@ -495,7 +504,12 @@ 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_person.local,
inserted_comment.id,
1,
);
CommentActions::like(pool, &comment_like).await?;
@ -506,7 +520,12 @@ 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,
another_inserted_person.local,
inserted_comment.id,
-1,
);
CommentActions::like(pool, &comment_dislike).await?;

View file

@ -440,7 +440,12 @@ 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,
inserted_person.local,
1,
);
let _inserted_post_like = PostActions::like(pool, &post_like).await?;
let comment_form = CommentInsertForm::new(
@ -450,7 +455,12 @@ 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_person.local,
inserted_comment.id,
1,
);
let _inserted_comment_like = CommentActions::like(pool, &comment_like).await?;
@ -462,8 +472,12 @@ mod tests {
let inserted_child_comment =
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);
let child_comment_like = CommentLikeForm::new(
another_inserted_person.id,
another_inserted_person.local,
inserted_child_comment.id,
1,
);
let _inserted_child_comment_like = CommentActions::like(pool, &child_comment_like).await?;

View file

@ -446,10 +446,14 @@ impl ReadComments for PostActions {
}
impl PostActions {
pub fn build_many_read_forms(post_ids: &[PostId], person_id: PersonId) -> Vec<PostReadForm> {
pub fn build_many_read_forms(
post_ids: &[PostId],
person_id: PersonId,
person_local: bool,
) -> Vec<PostReadForm> {
post_ids
.iter()
.map(|post_id| (PostReadForm::new(*post_id, person_id)))
.map(|post_id| (PostReadForm::new(*post_id, person_id, person_local)))
.collect::<Vec<_>>()
}
}
@ -591,21 +595,26 @@ 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,
inserted_person.local,
1,
);
let inserted_post_like = PostActions::like(pool, &post_like_form).await?;
assert_eq!(Some(1), inserted_post_like.like_score);
// Post Save
let post_saved_form = PostSavedForm::new(inserted_post.id, inserted_person.id);
let post_saved_form = PostSavedForm::new(inserted_post.id, inserted_person.id, inserted_person.local);
let inserted_post_saved = PostActions::save(pool, &post_saved_form).await?;
assert!(inserted_post_saved.saved.is_some());
// Mark 2 posts as read
let post_read_form_1 = PostReadForm::new(inserted_post.id, inserted_person.id);
let post_read_form_1 = PostReadForm::new(inserted_post.id, inserted_person.id, inserted_person.local);
PostActions::mark_as_read(pool, &post_read_form_1).await?;
let post_read_form_2 = PostReadForm::new(inserted_post2.id, inserted_person.id);
let post_read_form_2 = PostReadForm::new(inserted_post2.id, inserted_person.id, inserted_person.local);
PostActions::mark_as_read(pool, &post_read_form_2).await?;
let read_post = Post::read(pool, inserted_post.id).await?;
@ -625,11 +634,11 @@ mod tests {
let saved_removed = PostActions::unsave(pool, &post_saved_form).await?;
assert_eq!(uplete::Count::only_updated(1), saved_removed);
let read_remove_form_1 = PostReadForm::new(inserted_post.id, inserted_person.id);
let read_remove_form_1 = PostReadForm::new(inserted_post.id, inserted_person.id, inserted_person.local);
let read_removed_1 = PostActions::mark_as_unread(pool, &read_remove_form_1).await?;
assert_eq!(uplete::Count::only_deleted(1), read_removed_1);
let read_remove_form_2 = PostReadForm::new(inserted_post2.id, inserted_person.id);
let read_remove_form_2 = PostReadForm::new(inserted_post2.id, inserted_person.id, inserted_person.local);
let read_removed_2 = PostActions::mark_as_unread(pool, &read_remove_form_2).await?;
assert_eq!(uplete::Count::only_deleted(1), read_removed_2);
@ -694,7 +703,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, inserted_person.local, 1);
PostActions::like(pool, &post_like).await?;
@ -706,7 +715,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, another_inserted_person.local, -1);
PostActions::like(pool, &post_dislike).await?;

View file

@ -150,6 +150,8 @@ pub struct CommentActions {
#[cfg_attr(feature = "full", ts(optional))]
/// When the comment was saved.
pub saved: Option<DateTime<Utc>>,
/// When the person is local.
pub person_local: bool,
}
#[derive(Clone, derive_new::new)]
@ -160,6 +162,7 @@ pub struct CommentActions {
#[cfg_attr(feature = "full", diesel(table_name = comment_actions))]
pub struct CommentLikeForm {
pub person_id: PersonId,
pub person_local: bool,
pub comment_id: CommentId,
pub like_score: i16,
#[new(value = "Utc::now()")]
@ -171,6 +174,7 @@ pub struct CommentLikeForm {
#[cfg_attr(feature = "full", diesel(table_name = comment_actions))]
pub struct CommentSavedForm {
pub person_id: PersonId,
pub person_local: bool,
pub comment_id: CommentId,
#[new(value = "Utc::now()")]
pub saved: DateTime<Utc>,

View file

@ -222,6 +222,8 @@ pub struct PostActions {
#[cfg_attr(feature = "full", ts(optional))]
/// When the post was hidden.
pub hidden: Option<DateTime<Utc>>,
/// When the person is local.
pub person_local: bool,
}
#[derive(Clone, derive_new::new)]
@ -233,6 +235,7 @@ pub struct PostActions {
pub struct PostLikeForm {
pub post_id: PostId,
pub person_id: PersonId,
pub person_local: bool,
pub like_score: i16,
#[new(value = "Utc::now()")]
pub liked: DateTime<Utc>,
@ -244,6 +247,7 @@ pub struct PostLikeForm {
pub struct PostSavedForm {
pub post_id: PostId,
pub person_id: PersonId,
pub person_local: bool,
#[new(value = "Utc::now()")]
pub saved: DateTime<Utc>,
}
@ -254,6 +258,7 @@ pub struct PostSavedForm {
pub struct PostReadForm {
pub post_id: PostId,
pub person_id: PersonId,
pub person_local: bool,
#[new(value = "Utc::now()")]
pub read: DateTime<Utc>,
}
@ -264,6 +269,7 @@ pub struct PostReadForm {
pub struct PostReadCommentsForm {
pub post_id: PostId,
pub person_id: PersonId,
pub person_local: bool,
pub read_comments_amount: i64,
#[new(value = "Utc::now()")]
pub read_comments: DateTime<Utc>,
@ -275,6 +281,7 @@ pub struct PostReadCommentsForm {
pub struct PostHideForm {
pub post_id: PostId,
pub person_id: PersonId,
pub person_local: bool,
#[new(value = "Utc::now()")]
pub hidden: DateTime<Utc>,
}

View file

@ -67,17 +67,14 @@ CREATE FUNCTION r.parent_comment_ids (path ltree)
RETURNS SETOF int
LANGUAGE sql
IMMUTABLE parallel safe
BEGIN
ATOMIC
BEGIN ATOMIC
SELECT
comment_id::int
FROM
string_to_table (ltree2text (path), '.') AS comment_id
-- Skip first and last
LIMIT (nlevel (path) - 2) OFFSET 1;
END;
CALL r.create_triggers ('comment', $$
BEGIN
-- Prevent infinite recursion
@ -86,9 +83,7 @@ BEGIN
count(*)
FROM select_old_and_new_rows AS old_and_new_rows) = 0 THEN
RETURN NULL;
END IF;
UPDATE
person AS a
SET
@ -106,7 +101,6 @@ FROM (
WHERE
a.id = diff.creator_id
AND diff.comment_count != 0;
UPDATE
comment AS a
SET
@ -144,7 +138,6 @@ FROM (
WHERE
a.id = diff.parent_id
AND diff.child_count != 0;
UPDATE
post AS a
SET
@ -176,7 +169,6 @@ WHERE
GREATEST (a.newest_comment_time_necro, diff.newest_comment_time_necro)) != (0,
a.newest_comment_time,
a.newest_comment_time_necro);
UPDATE
local_site AS a
SET
@ -191,13 +183,9 @@ FROM (
AND (comment).local) AS diff
WHERE
diff.comments != 0;
RETURN NULL;
END;
$$);
CALL r.create_triggers ('post', $$
BEGIN
UPDATE
@ -214,7 +202,6 @@ BEGIN
WHERE
a.id = diff.creator_id
AND diff.post_count != 0;
UPDATE
community AS a
SET
@ -236,7 +223,6 @@ WHERE
AND (diff.posts,
diff.comments) != (0,
0);
UPDATE
local_site AS a
SET
@ -251,13 +237,9 @@ FROM (
AND (post).local) AS diff
WHERE
diff.posts != 0;
RETURN NULL;
END;
$$);
CALL r.create_triggers ('community', $$
BEGIN
UPDATE
@ -273,13 +255,9 @@ BEGIN
AND (community).local) AS diff
WHERE
diff.communities != 0;
RETURN NULL;
END;
$$);
CALL r.create_triggers ('local_user', $$
BEGIN
UPDATE
@ -293,13 +271,9 @@ BEGIN
WHERE (local_user).accepted_application) AS diff
WHERE
diff.users != 0;
RETURN NULL;
END;
$$);
-- Count subscribers for communities.
-- subscribers should be updated only when a local community is followed by a local or remote person.
-- subscribers_local should be updated only when a local person follows a local or remote community.
@ -319,13 +293,9 @@ BEGIN
WHERE
a.id = diff.community_id
AND (diff.subscribers, diff.subscribers_local) != (0, 0);
RETURN NULL;
END;
$$);
CALL r.create_triggers ('post_report', $$
BEGIN
UPDATE
@ -339,13 +309,9 @@ BEGIN
FROM select_old_and_new_rows AS old_and_new_rows GROUP BY (post_report).post_id) AS diff
WHERE (diff.report_count, diff.unresolved_report_count) != (0, 0)
AND a.id = diff.post_id;
RETURN NULL;
END;
$$);
CALL r.create_triggers ('comment_report', $$
BEGIN
UPDATE
@ -359,13 +325,9 @@ BEGIN
FROM select_old_and_new_rows AS old_and_new_rows GROUP BY (comment_report).comment_id) AS diff
WHERE (diff.report_count, diff.unresolved_report_count) != (0, 0)
AND a.id = diff.comment_id;
RETURN NULL;
END;
$$);
CALL r.create_triggers ('community_report', $$
BEGIN
UPDATE
@ -378,13 +340,9 @@ BEGIN
FROM select_old_and_new_rows AS old_and_new_rows GROUP BY (community_report).community_id) AS diff
WHERE (diff.report_count, diff.unresolved_report_count) != (0, 0)
AND a.id = diff.community_id;
RETURN NULL;
END;
$$);
-- Change the order of some cascading deletions to make deletion triggers run before the deletion of rows that the triggers need to read
CREATE FUNCTION r.delete_follow_before_person ()
RETURNS TRIGGER
@ -396,12 +354,10 @@ BEGIN
RETURN OLD;
END;
$$;
CREATE TRIGGER delete_follow
BEFORE DELETE ON person
FOR EACH ROW
EXECUTE FUNCTION r.delete_follow_before_person ();
-- Triggers that change values before insert or update
CREATE FUNCTION r.comment_change_values ()
RETURNS TRIGGER
@ -421,12 +377,10 @@ BEGIN
RETURN NEW;
END
$$;
CREATE TRIGGER change_values
BEFORE INSERT OR UPDATE ON comment
FOR EACH ROW
EXECUTE FUNCTION r.comment_change_values ();
CREATE FUNCTION r.post_change_values ()
RETURNS TRIGGER
LANGUAGE plpgsql
@ -442,12 +396,10 @@ BEGIN
RETURN NEW;
END
$$;
CREATE TRIGGER change_values
BEFORE INSERT ON post
FOR EACH ROW
EXECUTE FUNCTION r.post_change_values ();
CREATE FUNCTION r.private_message_change_values ()
RETURNS TRIGGER
LANGUAGE plpgsql
@ -460,12 +412,10 @@ BEGIN
RETURN NEW;
END
$$;
CREATE TRIGGER change_values
BEFORE INSERT ON private_message
FOR EACH ROW
EXECUTE FUNCTION r.private_message_change_values ();
-- Combined tables triggers
-- These insert (published, item_id) into X_combined tables
-- Reports (comment_report, post_report, private_message_report)
@ -491,15 +441,10 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_report_combined_trigger ('post_report');
CALL r.create_report_combined_trigger ('comment_report');
CALL r.create_report_combined_trigger ('private_message_report');
CALL r.create_report_combined_trigger ('community_report');
-- person_content (comment, post)
CREATE PROCEDURE r.create_person_content_combined_trigger (table_name text)
LANGUAGE plpgsql
@ -523,11 +468,8 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_person_content_combined_trigger ('post');
CALL r.create_person_content_combined_trigger ('comment');
-- person_saved (comment, post)
-- This one is a little different, because it triggers using x_actions.saved,
-- Rather than any row insert
@ -562,8 +504,14 @@ BEGIN
END IF;
RETURN NULL;
END $$;
CREATE TRIGGER person_saved_combined
AFTER INSERT OR DELETE OR UPDATE OF saved ON thing_actions
CREATE TRIGGER person_saved_combined_insert_update
AFTER INSERT OR UPDATE OF saved ON thing_actions
FOR EACH ROW
-- Only save for local users
WHEN (NEW.person_local = TRUE )
EXECUTE FUNCTION r.person_saved_combined_change_values_thing ( );
CREATE TRIGGER person_saved_combined_delete
AFTER DELETE ON thing_actions
FOR EACH ROW
EXECUTE FUNCTION r.person_saved_combined_change_values_thing ( );
$b$,
@ -571,11 +519,8 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_person_saved_combined_trigger ('post');
CALL r.create_person_saved_combined_trigger ('comment');
-- person_liked (comment, post)
-- This one is a little different, because it triggers using x_actions.liked,
-- Rather than any row insert
@ -610,8 +555,14 @@ BEGIN
END IF;
RETURN NULL;
END $$;
CREATE TRIGGER person_liked_combined
AFTER INSERT OR DELETE OR UPDATE OF liked ON thing_actions
CREATE TRIGGER person_liked_combined_insert_update
AFTER INSERT OR UPDATE OF liked ON thing_actions
FOR EACH ROW
-- Only save for local users
WHEN (NEW.person_local = TRUE )
EXECUTE FUNCTION r.person_liked_combined_change_values_thing ( );
CREATE TRIGGER person_liked_combined_delete
AFTER DELETE ON thing_actions
FOR EACH ROW
EXECUTE FUNCTION r.person_liked_combined_change_values_thing ( );
$b$,
@ -619,11 +570,8 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_person_liked_combined_trigger ('post');
CALL r.create_person_liked_combined_trigger ('comment');
-- modlog: (17 tables)
-- admin_allow_instance
-- admin_block_instance
@ -664,41 +612,23 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_modlog_combined_trigger ('admin_allow_instance');
CALL r.create_modlog_combined_trigger ('admin_block_instance');
CALL r.create_modlog_combined_trigger ('admin_purge_comment');
CALL r.create_modlog_combined_trigger ('admin_purge_community');
CALL r.create_modlog_combined_trigger ('admin_purge_person');
CALL r.create_modlog_combined_trigger ('admin_purge_post');
CALL r.create_modlog_combined_trigger ('mod_add');
CALL r.create_modlog_combined_trigger ('mod_add_community');
CALL r.create_modlog_combined_trigger ('mod_ban');
CALL r.create_modlog_combined_trigger ('mod_ban_from_community');
CALL r.create_modlog_combined_trigger ('mod_feature_post');
CALL r.create_modlog_combined_trigger ('mod_change_community_visibility');
CALL r.create_modlog_combined_trigger ('mod_lock_post');
CALL r.create_modlog_combined_trigger ('mod_remove_comment');
CALL r.create_modlog_combined_trigger ('mod_remove_community');
CALL r.create_modlog_combined_trigger ('mod_remove_post');
CALL r.create_modlog_combined_trigger ('mod_transfer_community');
-- Inbox: (replies, comment mentions, post mentions, and private_messages)
CREATE PROCEDURE r.create_inbox_combined_trigger (table_name text)
LANGUAGE plpgsql
@ -722,15 +652,10 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_inbox_combined_trigger ('comment_reply');
CALL r.create_inbox_combined_trigger ('person_comment_mention');
CALL r.create_inbox_combined_trigger ('person_post_mention');
CALL r.create_inbox_combined_trigger ('private_message');
-- Prevent using delete instead of uplete on action tables
CREATE FUNCTION r.require_uplete ()
RETURNS TRIGGER
@ -743,32 +668,26 @@ BEGIN
RETURN NULL;
END
$$;
CREATE TRIGGER require_uplete
BEFORE DELETE ON comment_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON community_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON instance_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON person_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON post_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
-- search: (post, comment, community, person)
CREATE PROCEDURE r.create_search_combined_trigger (table_name text)
LANGUAGE plpgsql
@ -793,15 +712,10 @@ BEGIN
table_name);
END;
$a$;
CALL r.create_search_combined_trigger ('post');
CALL r.create_search_combined_trigger ('comment');
CALL r.create_search_combined_trigger ('community');
CALL r.create_search_combined_trigger ('person');
-- You also need to triggers to update the `score` column.
-- post | post::score
-- comment | comment_aggregates::score
@ -823,12 +737,10 @@ BEGIN
RETURN NULL;
END
$$;
CREATE TRIGGER search_combined_post_score
AFTER UPDATE OF score ON post
FOR EACH ROW
EXECUTE FUNCTION r.search_combined_post_score_update ();
-- Comment score
CREATE FUNCTION r.search_combined_comment_score_update ()
RETURNS TRIGGER
@ -844,12 +756,10 @@ BEGIN
RETURN NULL;
END
$$;
CREATE TRIGGER search_combined_comment_score
AFTER UPDATE OF score ON comment
FOR EACH ROW
EXECUTE FUNCTION r.search_combined_comment_score_update ();
-- Person score
CREATE FUNCTION r.search_combined_person_score_update ()
RETURNS TRIGGER
@ -865,12 +775,10 @@ BEGIN
RETURN NULL;
END
$$;
CREATE TRIGGER search_combined_person_score
AFTER UPDATE OF post_score ON person
FOR EACH ROW
EXECUTE FUNCTION r.search_combined_person_score_update ();
-- Community score
CREATE FUNCTION r.search_combined_community_score_update ()
RETURNS TRIGGER
@ -886,9 +794,7 @@ BEGIN
RETURN NULL;
END
$$;
CREATE TRIGGER search_combined_community_score
AFTER UPDATE OF users_active_month ON community
FOR EACH ROW
EXECUTE FUNCTION r.search_combined_community_score_update ();

View file

@ -149,6 +149,7 @@ diesel::table! {
like_score -> Nullable<Int2>,
liked -> Nullable<Timestamptz>,
saved -> Nullable<Timestamptz>,
person_local -> Bool,
}
}
@ -896,6 +897,7 @@ diesel::table! {
liked -> Nullable<Timestamptz>,
like_score -> Nullable<Int2>,
hidden -> Nullable<Timestamptz>,
person_local -> Bool,
}
}

View file

@ -446,7 +446,12 @@ 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,
inserted_timmy_person.local,
comment_0.id,
1,
);
CommentActions::like(pool, &comment_like_form).await?;

View file

@ -366,13 +366,15 @@ 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.timmy.local, data.sara_comment_2.id, 1);
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.timmy.local, data.sara_comment.id, -1);
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, data.timmy.local, 1);
PostActions::like(pool, &post_like_form).await?;
let timmy_liked_all = PersonLikedCombinedQuery::default()

View file

@ -355,14 +355,21 @@ mod tests {
assert_eq!(0, timmy_saved.len());
// Save a few things
let save_sara_comment_2 =
CommentSavedForm::new(data.timmy_view.person.id, data.sara_comment_2.id);
let save_sara_comment_2 = CommentSavedForm::new(
data.timmy_view.person.id,
data.timmy_view.person.local,
data.sara_comment_2.id,
);
CommentActions::save(pool, &save_sara_comment_2).await?;
let save_sara_comment = CommentSavedForm::new(data.timmy_view.person.id, data.sara_comment.id);
let save_sara_comment = CommentSavedForm::new(
data.timmy_view.person.id,
data.timmy_view.person.local,
data.sara_comment.id,
);
CommentActions::save(pool, &save_sara_comment).await?;
let post_save_form = PostSavedForm::new(data.timmy_post.id, data.timmy.id);
let post_save_form = PostSavedForm::new(data.timmy_post.id, data.timmy.id, data.timmy.local);
PostActions::save(pool, &post_save_form).await?;
let timmy_saved = PersonSavedCombinedQuery::default()

View file

@ -938,7 +938,12 @@ mod tests {
let pool = &data.pool();
let pool = &mut pool.into();
let post_like_form = PostLikeForm::new(data.post.id, data.tegan_local_user_view.person.id, 1);
let post_like_form = PostLikeForm::new(
data.post.id,
data.tegan_local_user_view.person.id,
data.tegan_local_user_view.person.local,
1,
);
let inserted_post_like = PostActions::like(pool, &post_like_form).await?;
@ -1010,12 +1015,18 @@ mod tests {
let pool = &mut pool.into();
// Mark the bot post, then the tags post as read
let bot_post_read_form =
PostReadForm::new(data.bot_post.id, data.tegan_local_user_view.person.id);
let bot_post_read_form = PostReadForm::new(
data.bot_post.id,
data.tegan_local_user_view.person.id,
data.tegan_local_user_view.person.local,
);
PostActions::mark_as_read(pool, &bot_post_read_form).await?;
let tag_post_read_form =
PostReadForm::new(data.post_with_tags.id, data.tegan_local_user_view.person.id);
let tag_post_read_form = PostReadForm::new(
data.post_with_tags.id,
data.tegan_local_user_view.person.id,
data.tegan_local_user_view.person.local,
);
PostActions::mark_as_read(pool, &tag_post_read_form).await?;
let read_read_post_listing =
@ -1588,7 +1599,11 @@ mod tests {
data.tegan_local_user_view.local_user.show_read_posts = false;
// Mark a post as read
let read_form = PostReadForm::new(data.bot_post.id, data.tegan_local_user_view.person.id);
let read_form = PostReadForm::new(
data.bot_post.id,
data.tegan_local_user_view.person.id,
data.tegan_local_user_view.person.local,
);
PostActions::mark_as_read(pool, &read_form).await?;
// Make sure you don't see the read post in the results
@ -1629,7 +1644,11 @@ mod tests {
let pool = &mut pool.into();
// Mark a post as hidden
let hide_form = PostHideForm::new(data.bot_post.id, data.tegan_local_user_view.person.id);
let hide_form = PostHideForm::new(
data.bot_post.id,
data.tegan_local_user_view.person.id,
data.tegan_local_user_view.person.local,
);
PostActions::hide(pool, &hide_form).await?;
// Make sure you don't see the hidden post in the results

View file

@ -533,22 +533,24 @@ mod tests {
let sara_comment_2 = Comment::create(pool, &sara_comment_form_2, 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, timmy.local, 1);
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, timmy.local, 1);
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, timmy.local, -1);
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.local, timmy_comment.id, 1);
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, timmy.local, sara_comment.id, 1);
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, timmy.local, sara_comment_2.id, -1);
CommentActions::like(pool, &timmy_dislike_sara_comment_form).await?;
Ok(Data {

View file

@ -235,11 +235,13 @@ 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, inserted_timmy.local, 1);
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, inserted_sara.local, -1);
PostActions::like(pool, &sara_post_vote_form).await?;
let mut expected_post_vote_views = [
@ -264,11 +266,21 @@ 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_timmy.local,
inserted_comment.id,
-1,
);
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_sara.local,
inserted_comment.id,
1,
);
CommentActions::like(pool, &sara_comment_vote_form).await?;
let mut expected_comment_vote_views = [

View file

@ -1,2 +1,8 @@
DROP TABLE person_liked_combined;
ALTER TABLE post_actions
DROP COLUMN person_local;
ALTER TABLE comment_actions
DROP COLUMN person_local;

View file

@ -19,6 +19,33 @@ CREATE INDEX idx_person_liked_combined_published ON person_liked_combined (liked
CREATE INDEX idx_person_liked_combined ON person_liked_combined (person_id);
-- In order to not store liked combined for federated users, add a person_local to post_actions and comment actions.
-- Your triggers for both person_saved_combined, and person_liked_combined, only needs local users.
ALTER TABLE post_actions
ADD COLUMN person_local boolean DEFAULT TRUE NOT NULL;
ALTER TABLE comment_actions
ADD COLUMN person_local boolean DEFAULT TRUE NOT NULL;
-- Update historical data for those tables now
UPDATE
post_actions pa
SET
person_local = p.local
FROM
person p
WHERE
pa.person_id = p.id;
UPDATE
comment_actions ca
SET
person_local = p.local
FROM
person p
WHERE
ca.person_id = p.id;
-- Updating the history
INSERT INTO person_liked_combined (liked, like_score, person_id, post_id, comment_id)
SELECT
@ -31,6 +58,7 @@ FROM
post_actions
WHERE
liked IS NOT NULL
AND person_local = TRUE
UNION ALL
SELECT
liked,
@ -41,5 +69,6 @@ SELECT
FROM
comment_actions
WHERE
liked IS NOT NULL;
liked IS NOT NULL
AND person_local = TRUE;