-- Person -- Drop the 2 views user_alias_1, user_alias_2 DROP VIEW user_alias_1, user_alias_2; -- rename the user_ table to person ALTER TABLE user_ RENAME TO person; ALTER SEQUENCE user__id_seq RENAME TO person_id_seq; -- create a new table local_user CREATE TABLE local_user ( id serial PRIMARY KEY, person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, password_encrypted text NOT NULL, email text UNIQUE, admin boolean DEFAULT FALSE NOT NULL, show_nsfw boolean DEFAULT FALSE NOT NULL, theme character varying(20) DEFAULT 'darkly' ::character varying NOT NULL, default_sort_type smallint DEFAULT 0 NOT NULL, default_listing_type smallint DEFAULT 1 NOT NULL, lang character varying(20) DEFAULT 'browser' ::character varying NOT NULL, show_avatars boolean DEFAULT TRUE NOT NULL, send_notifications_to_email boolean DEFAULT FALSE NOT NULL, matrix_user_id text, UNIQUE (person_id) ); -- Copy the local users over to the new table INSERT INTO local_user (person_id, password_encrypted, email, admin, show_nsfw, theme, default_sort_type, default_listing_type, lang, show_avatars, send_notifications_to_email, matrix_user_id) SELECT id, password_encrypted, email, admin, show_nsfw, theme, default_sort_type, default_listing_type, lang, show_avatars, send_notifications_to_email, matrix_user_id FROM person WHERE local = TRUE; -- Drop those columns from person ALTER TABLE person DROP COLUMN password_encrypted, DROP COLUMN email, DROP COLUMN admin, DROP COLUMN show_nsfw, DROP COLUMN theme, DROP COLUMN default_sort_type, DROP COLUMN default_listing_type, DROP COLUMN lang, DROP COLUMN show_avatars, DROP COLUMN send_notifications_to_email, DROP COLUMN matrix_user_id; -- Rename indexes ALTER INDEX user__pkey RENAME TO person__pkey; ALTER INDEX idx_user_actor_id RENAME TO idx_person_actor_id; ALTER INDEX idx_user_inbox_url RENAME TO idx_person_inbox_url; ALTER INDEX idx_user_lower_actor_id RENAME TO idx_person_lower_actor_id; ALTER INDEX idx_user_published RENAME TO idx_person_published; -- Rename triggers ALTER TRIGGER site_aggregates_user_delete ON person RENAME TO site_aggregates_person_delete; ALTER TRIGGER site_aggregates_user_insert ON person RENAME TO site_aggregates_person_insert; -- Rename the trigger functions ALTER FUNCTION site_aggregates_user_delete () RENAME TO site_aggregates_person_delete; ALTER FUNCTION site_aggregates_user_insert () RENAME TO site_aggregates_person_insert; -- Create views CREATE VIEW person_alias_1 AS SELECT * FROM person; CREATE VIEW person_alias_2 AS SELECT * FROM person; -- Redo user aggregates into person_aggregates ALTER TABLE user_aggregates RENAME TO person_aggregates; ALTER SEQUENCE user_aggregates_id_seq RENAME TO person_aggregates_id_seq; ALTER TABLE person_aggregates RENAME COLUMN user_id TO person_id; -- index ALTER INDEX user_aggregates_pkey RENAME TO person_aggregates_pkey; ALTER INDEX idx_user_aggregates_comment_score RENAME TO idx_person_aggregates_comment_score; ALTER INDEX user_aggregates_user_id_key RENAME TO person_aggregates_person_id_key; ALTER TABLE person_aggregates RENAME CONSTRAINT user_aggregates_user_id_fkey TO person_aggregates_person_id_fkey; -- Drop all the old triggers and functions DROP TRIGGER user_aggregates_user ON person; DROP TRIGGER user_aggregates_post_count ON post; DROP TRIGGER user_aggregates_post_score ON post_like; DROP TRIGGER user_aggregates_comment_count ON comment; DROP TRIGGER user_aggregates_comment_score ON comment_like; DROP FUNCTION user_aggregates_user, user_aggregates_post_count, user_aggregates_post_score, user_aggregates_comment_count, user_aggregates_comment_score; -- initial user add CREATE FUNCTION person_aggregates_person () RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF (TG_OP = 'INSERT') THEN INSERT INTO person_aggregates (person_id) VALUES (NEW.id); ELSIF (TG_OP = 'DELETE') THEN DELETE FROM person_aggregates WHERE person_id = OLD.id; END IF; RETURN NULL; END $$; CREATE TRIGGER person_aggregates_person AFTER INSERT OR DELETE ON person FOR EACH ROW EXECUTE PROCEDURE person_aggregates_person (); -- post count CREATE FUNCTION person_aggregates_post_count () RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF (TG_OP = 'INSERT') THEN UPDATE person_aggregates SET post_count = post_count + 1 WHERE person_id = NEW.creator_id; ELSIF (TG_OP = 'DELETE') THEN UPDATE person_aggregates SET post_count = post_count - 1 WHERE person_id = OLD.creator_id; -- If the post gets deleted, the score calculation trigger won't fire, -- so you need to re-calculate UPDATE person_aggregates ua SET post_score = pd.score FROM ( SELECT u.id, coalesce(0, sum(pl.score)) AS score -- User join because posts could be empty FROM person u LEFT JOIN post p ON u.id = p.creator_id LEFT JOIN post_like pl ON p.id = pl.post_id GROUP BY u.id) pd WHERE ua.person_id = OLD.creator_id; END IF; RETURN NULL; END $$; CREATE TRIGGER person_aggregates_post_count AFTER INSERT OR DELETE ON post FOR EACH ROW EXECUTE PROCEDURE person_aggregates_post_count (); -- post score CREATE FUNCTION person_aggregates_post_score () RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF (TG_OP = 'INSERT') THEN -- Need to get the post creator, not the voter UPDATE person_aggregates ua SET post_score = post_score + NEW.score FROM post p WHERE ua.person_id = p.creator_id AND p.id = NEW.post_id; ELSIF (TG_OP = 'DELETE') THEN UPDATE person_aggregates ua SET post_score = post_score - OLD.score FROM post p WHERE ua.person_id = p.creator_id AND p.id = OLD.post_id; END IF; RETURN NULL; END $$; CREATE TRIGGER person_aggregates_post_score AFTER INSERT OR DELETE ON post_like FOR EACH ROW EXECUTE PROCEDURE person_aggregates_post_score (); -- comment count CREATE FUNCTION person_aggregates_comment_count () RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF (TG_OP = 'INSERT') THEN UPDATE person_aggregates SET comment_count = comment_count + 1 WHERE person_id = NEW.creator_id; ELSIF (TG_OP = 'DELETE') THEN UPDATE person_aggregates SET comment_count = comment_count - 1 WHERE person_id = OLD.creator_id; -- If the comment gets deleted, the score calculation trigger won't fire, -- so you need to re-calculate UPDATE person_aggregates ua SET comment_score = cd.score FROM ( SELECT u.id, coalesce(0, sum(cl.score)) AS score -- User join because comments could be empty FROM person u LEFT JOIN comment c ON u.id = c.creator_id LEFT JOIN comment_like cl ON c.id = cl.comment_id GROUP BY u.id) cd WHERE ua.person_id = OLD.creator_id; END IF; RETURN NULL; END $$; CREATE TRIGGER person_aggregates_comment_count AFTER INSERT OR DELETE ON comment FOR EACH ROW EXECUTE PROCEDURE person_aggregates_comment_count (); -- comment score CREATE FUNCTION person_aggregates_comment_score () RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN IF (TG_OP = 'INSERT') THEN -- Need to get the post creator, not the voter UPDATE person_aggregates ua SET comment_score = comment_score + NEW.score FROM comment c WHERE ua.person_id = c.creator_id AND c.id = NEW.comment_id; ELSIF (TG_OP = 'DELETE') THEN UPDATE person_aggregates ua SET comment_score = comment_score - OLD.score FROM comment c WHERE ua.person_id = c.creator_id AND c.id = OLD.comment_id; END IF; RETURN NULL; END $$; CREATE TRIGGER person_aggregates_comment_score AFTER INSERT OR DELETE ON comment_like FOR EACH ROW EXECUTE PROCEDURE person_aggregates_comment_score (); -- person_mention ALTER TABLE user_mention RENAME TO person_mention; ALTER SEQUENCE user_mention_id_seq RENAME TO person_mention_id_seq; ALTER INDEX user_mention_pkey RENAME TO person_mention_pkey; ALTER INDEX user_mention_recipient_id_comment_id_key RENAME TO person_mention_recipient_id_comment_id_key; ALTER TABLE person_mention RENAME CONSTRAINT user_mention_comment_id_fkey TO person_mention_comment_id_fkey; ALTER TABLE person_mention RENAME CONSTRAINT user_mention_recipient_id_fkey TO person_mention_recipient_id_fkey; -- user_ban ALTER TABLE user_ban RENAME TO person_ban; ALTER SEQUENCE user_ban_id_seq RENAME TO person_ban_id_seq; ALTER INDEX user_ban_pkey RENAME TO person_ban_pkey; ALTER INDEX user_ban_user_id_key RENAME TO person_ban_person_id_key; ALTER TABLE person_ban RENAME COLUMN user_id TO person_id; ALTER TABLE person_ban RENAME CONSTRAINT user_ban_user_id_fkey TO person_ban_person_id_fkey; -- comment_like ALTER TABLE comment_like RENAME COLUMN user_id TO person_id; ALTER INDEX idx_comment_like_user RENAME TO idx_comment_like_person; ALTER TABLE comment_like RENAME CONSTRAINT comment_like_comment_id_user_id_key TO comment_like_comment_id_person_id_key; ALTER TABLE comment_like RENAME CONSTRAINT comment_like_user_id_fkey TO comment_like_person_id_fkey; -- comment_saved ALTER TABLE comment_saved RENAME COLUMN user_id TO person_id; ALTER TABLE comment_saved RENAME CONSTRAINT comment_saved_comment_id_user_id_key TO comment_saved_comment_id_person_id_key; ALTER TABLE comment_saved RENAME CONSTRAINT comment_saved_user_id_fkey TO comment_saved_person_id_fkey; -- community_follower ALTER TABLE community_follower RENAME COLUMN user_id TO person_id; ALTER TABLE community_follower RENAME CONSTRAINT community_follower_community_id_user_id_key TO community_follower_community_id_person_id_key; ALTER TABLE community_follower RENAME CONSTRAINT community_follower_user_id_fkey TO community_follower_person_id_fkey; -- community_moderator ALTER TABLE community_moderator RENAME COLUMN user_id TO person_id; ALTER TABLE community_moderator RENAME CONSTRAINT community_moderator_community_id_user_id_key TO community_moderator_community_id_person_id_key; ALTER TABLE community_moderator RENAME CONSTRAINT community_moderator_user_id_fkey TO community_moderator_person_id_fkey; -- community_user_ban ALTER TABLE community_user_ban RENAME TO community_person_ban; ALTER SEQUENCE community_user_ban_id_seq RENAME TO community_person_ban_id_seq; ALTER TABLE community_person_ban RENAME COLUMN user_id TO person_id; ALTER TABLE community_person_ban RENAME CONSTRAINT community_user_ban_pkey TO community_person_ban_pkey; ALTER TABLE community_person_ban RENAME CONSTRAINT community_user_ban_community_id_fkey TO community_person_ban_community_id_fkey; ALTER TABLE community_person_ban RENAME CONSTRAINT community_user_ban_community_id_user_id_key TO community_person_ban_community_id_person_id_key; ALTER TABLE community_person_ban RENAME CONSTRAINT community_user_ban_user_id_fkey TO community_person_ban_person_id_fkey; -- mod_add ALTER TABLE mod_add RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_add RENAME COLUMN other_user_id TO other_person_id; ALTER TABLE mod_add RENAME CONSTRAINT mod_add_mod_user_id_fkey TO mod_add_mod_person_id_fkey; ALTER TABLE mod_add RENAME CONSTRAINT mod_add_other_user_id_fkey TO mod_add_other_person_id_fkey; -- mod_add_community ALTER TABLE mod_add_community RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_add_community RENAME COLUMN other_user_id TO other_person_id; ALTER TABLE mod_add_community RENAME CONSTRAINT mod_add_community_mod_user_id_fkey TO mod_add_community_mod_person_id_fkey; ALTER TABLE mod_add_community RENAME CONSTRAINT mod_add_community_other_user_id_fkey TO mod_add_community_other_person_id_fkey; -- mod_ban ALTER TABLE mod_ban RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_ban RENAME COLUMN other_user_id TO other_person_id; ALTER TABLE mod_ban RENAME CONSTRAINT mod_ban_mod_user_id_fkey TO mod_ban_mod_person_id_fkey; ALTER TABLE mod_ban RENAME CONSTRAINT mod_ban_other_user_id_fkey TO mod_ban_other_person_id_fkey; -- mod_ban_community ALTER TABLE mod_ban_from_community RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_ban_from_community RENAME COLUMN other_user_id TO other_person_id; ALTER TABLE mod_ban_from_community RENAME CONSTRAINT mod_ban_from_community_mod_user_id_fkey TO mod_ban_from_community_mod_person_id_fkey; ALTER TABLE mod_ban_from_community RENAME CONSTRAINT mod_ban_from_community_other_user_id_fkey TO mod_ban_from_community_other_person_id_fkey; -- mod_lock_post ALTER TABLE mod_lock_post RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_lock_post RENAME CONSTRAINT mod_lock_post_mod_user_id_fkey TO mod_lock_post_mod_person_id_fkey; -- mod_remove_comment ALTER TABLE mod_remove_comment RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_remove_comment RENAME CONSTRAINT mod_remove_comment_mod_user_id_fkey TO mod_remove_comment_mod_person_id_fkey; -- mod_remove_community ALTER TABLE mod_remove_community RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_remove_community RENAME CONSTRAINT mod_remove_community_mod_user_id_fkey TO mod_remove_community_mod_person_id_fkey; -- mod_remove_post ALTER TABLE mod_remove_post RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_remove_post RENAME CONSTRAINT mod_remove_post_mod_user_id_fkey TO mod_remove_post_mod_person_id_fkey; -- mod_sticky_post ALTER TABLE mod_sticky_post RENAME COLUMN mod_user_id TO mod_person_id; ALTER TABLE mod_sticky_post RENAME CONSTRAINT mod_sticky_post_mod_user_id_fkey TO mod_sticky_post_mod_person_id_fkey; -- password_reset_request DELETE FROM password_reset_request; ALTER TABLE password_reset_request DROP COLUMN user_id; ALTER TABLE password_reset_request ADD COLUMN local_user_id integer NOT NULL REFERENCES local_user (id) ON UPDATE CASCADE ON DELETE CASCADE; -- post_like ALTER TABLE post_like RENAME COLUMN user_id TO person_id; ALTER INDEX idx_post_like_user RENAME TO idx_post_like_person; ALTER TABLE post_like RENAME CONSTRAINT post_like_post_id_user_id_key TO post_like_post_id_person_id_key; ALTER TABLE post_like RENAME CONSTRAINT post_like_user_id_fkey TO post_like_person_id_fkey; -- post_read ALTER TABLE post_read RENAME COLUMN user_id TO person_id; ALTER TABLE post_read RENAME CONSTRAINT post_read_post_id_user_id_key TO post_read_post_id_person_id_key; ALTER TABLE post_read RENAME CONSTRAINT post_read_user_id_fkey TO post_read_person_id_fkey; -- post_saved ALTER TABLE post_saved RENAME COLUMN user_id TO person_id; ALTER TABLE post_saved RENAME CONSTRAINT post_saved_post_id_user_id_key TO post_saved_post_id_person_id_key; ALTER TABLE post_saved RENAME CONSTRAINT post_saved_user_id_fkey TO post_saved_person_id_fkey; -- redo site aggregates trigger CREATE OR REPLACE FUNCTION site_aggregates_activity (i text) RETURNS integer LANGUAGE plpgsql AS $$ DECLARE count_ integer; BEGIN SELECT count(*) INTO count_ FROM ( SELECT c.creator_id FROM comment c INNER JOIN person u ON c.creator_id = u.id WHERE c.published > ('now'::timestamp - i::interval) AND u.local = TRUE UNION SELECT p.creator_id FROM post p INNER JOIN person u ON p.creator_id = u.id WHERE p.published > ('now'::timestamp - i::interval) AND u.local = TRUE) a; RETURN count_; END; $$;