lemmy/migrations/2024-01-05-213000_community_aggregates_add_local_subscribers/up.sql
İsmail Karslı 8670403a67
Add local_subscribers field to CommunityAggregates. Fixes #4144 (#4166)
* Add upload timeout to PictrsConfig

* Bad space 🤔

* Update PictrsConfig upload timeout to include units.

* Add local_subscribers field to CommunityAggregates
struct and schema

* sql format

* local_subscribers test

* fix local_subscribers test

* Revert "fix local_subscribers test"

This reverts commit 4bbac5ce4a.

* Revert "local_subscribers test"

This reverts commit 735107e1f7.

* Create trigger for local_subscribers

* Rename variable

* re-trigger ci

* re-trigger ci

* Add local_subscribers count to follow.spec.ts

* Rename local_subscribers to subscribers_local

* Add subscribers_local to community_aggregates

* added subscribers_local to the aggregate tests

* Check if person exists on community_follower trigger

* Delete community follows before deleting person

* Update lemmy-js-client in api_tests

* Refactor local_subscriber migration

* fix format

* Move migration files date to now

* Fix test to wait for aggregates to federate

* re-trigger ci

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
2024-01-24 10:22:05 -05:00

82 lines
2.4 KiB
PL/PgSQL

-- Couldn't find a way to put subscribers_local right after subscribers except recreating the table.
ALTER TABLE community_aggregates
ADD COLUMN subscribers_local bigint NOT NULL DEFAULT 0;
-- update initial value
-- update by counting local persons who follow communities.
WITH follower_counts AS (
SELECT
community_id,
count(*) AS local_sub_count
FROM
community_follower cf
JOIN person p ON p.id = cf.person_id
WHERE
p.local = TRUE
GROUP BY
community_id)
UPDATE
community_aggregates ca
SET
subscribers_local = local_sub_count
FROM
follower_counts
WHERE
ca.community_id = follower_counts.community_id;
-- 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
CREATE OR REPLACE FUNCTION community_aggregates_subscriber_count ()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF (TG_OP = 'INSERT') THEN
UPDATE
community_aggregates ca
SET
subscribers = subscribers + community.local::int,
subscribers_local = subscribers_local + person.local::int
FROM
community
LEFT JOIN person ON person.id = NEW.person_id
WHERE
community.id = NEW.community_id
AND community.id = ca.community_id
AND person.local IS NOT NULL;
ELSIF (TG_OP = 'DELETE') THEN
UPDATE
community_aggregates ca
SET
subscribers = subscribers - community.local::int,
subscribers_local = subscribers_local - person.local::int
FROM
community
LEFT JOIN person ON person.id = OLD.person_id
WHERE
community.id = OLD.community_id
AND community.id = ca.community_id
AND person.local IS NOT NULL;
END IF;
RETURN NULL;
END
$$;
-- to be able to join person on the trigger above, we need to run it before the person is deleted: https://github.com/LemmyNet/lemmy/pull/4166#issuecomment-1874095856
CREATE FUNCTION delete_follow_before_person ()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
DELETE FROM community_follower AS c
WHERE c.person_id = OLD.id;
RETURN OLD;
END;
$$;
CREATE TRIGGER delete_follow_before_person
BEFORE DELETE ON person
FOR EACH ROW
EXECUTE FUNCTION delete_follow_before_person ();