From: Dessalines <dessalines@users.noreply.github.com> Date: Wed, 2 Aug 2023 16:44:51 +0000 (-0400) Subject: Adding SQL format checking via `pg_format` / pgFormatter (#3740) X-Git-Url: http://these/git/%22%7Burl%7D/static/README.md?a=commitdiff_plain;h=be1389420b9dc4516f1e9b3e82637f84919a438e;p=lemmy.git Adding SQL format checking via `pg_format` / pgFormatter (#3740) * SQL format checking, 1. * SQL format checking, 2. * SQL format checking, 3. * SQL format checking, 4. * SQL format checking, 5. * Running pg_format * Getting rid of comment. * Upping pg_format version. * Using git ls-files for sql format check. * Fixing sql lints. * Addressing PR comments. --- diff --git a/.woodpecker.yml b/.woodpecker.yml index 91779122..a3c1f119 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -83,6 +83,18 @@ pipeline: - rustup component add rustfmt --toolchain nightly-2023-07-10 - cargo +nightly-2023-07-10 fmt -- --check + sql_fmt: + image: alpine:3 + commands: + - apk add bash wget perl make git + - wget https://github.com/darold/pgFormatter/archive/refs/tags/v5.5.tar.gz + - tar xzf v5.5.tar.gz + - cd pgFormatter-5.5 + - perl Makefile.PL + - make && make install + - cd .. + - ./scripts/./sql_format_check.sh + # make sure api builds with default features (used by other crates relying on lemmy api) check_api_common_default_features: image: *muslrust_image @@ -145,7 +157,7 @@ pipeline: environment: CARGO_HOME: .cargo commands: - # when adding new clippy lints, make sure to also add them in scripts/fix-clippy.sh + # when adding new clippy lints, make sure to also add them in scripts/lint.sh - rustup component add clippy - cargo clippy --workspace --tests --all-targets --features console -- -D warnings -D deprecated -D clippy::perf -D clippy::complexity diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql index a9f52609..5e29318c 100644 --- a/migrations/00000000000000_diesel_initial_setup/down.sql +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -1,6 +1,7 @@ -- This file was automatically created by Diesel to setup helper functions -- and other internal bookkeeping. This file is safe to edit, any future -- changes will be added to existing projects as new migrations. +DROP FUNCTION IF EXISTS diesel_manage_updated_at (_tbl regclass); + +DROP FUNCTION IF EXISTS diesel_set_updated_at (); -DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql index d68895b1..246f5e47 100644 --- a/migrations/00000000000000_diesel_initial_setup/up.sql +++ b/migrations/00000000000000_diesel_initial_setup/up.sql @@ -1,10 +1,6 @@ -- This file was automatically created by Diesel to setup helper functions -- and other internal bookkeeping. This file is safe to edit, any future -- changes will be added to existing projects as new migrations. - - - - -- Sets up a trigger for the given table to automatically set a column called -- `updated_at` whenever the row is modified (unless `updated_at` was included -- in the modified columns) @@ -16,21 +12,25 @@ -- -- SELECT diesel_manage_updated_at('users'); -- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +CREATE OR REPLACE FUNCTION diesel_manage_updated_at (_tbl regclass) + RETURNS VOID + AS $$ BEGIN EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); END; -$$ LANGUAGE plpgsql; +$$ +LANGUAGE plpgsql; -CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +CREATE OR REPLACE FUNCTION diesel_set_updated_at () + RETURNS TRIGGER + AS $$ BEGIN - IF ( - NEW IS DISTINCT FROM OLD AND - NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at - ) THEN - NEW.updated_at := current_timestamp; + IF (NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at) THEN + NEW.updated_at := CURRENT_TIMESTAMP; END IF; RETURN NEW; END; -$$ LANGUAGE plpgsql; +$$ +LANGUAGE plpgsql; + diff --git a/migrations/2019-02-26-002946_create_user/down.sql b/migrations/2019-02-26-002946_create_user/down.sql index 67a280d6..a9bfa3fe 100644 --- a/migrations/2019-02-26-002946_create_user/down.sql +++ b/migrations/2019-02-26-002946_create_user/down.sql @@ -1,2 +1,4 @@ -drop table user_ban; -drop table user_; +DROP TABLE user_ban; + +DROP TABLE user_; + diff --git a/migrations/2019-02-26-002946_create_user/up.sql b/migrations/2019-02-26-002946_create_user/up.sql index ea2c9234..251938fe 100644 --- a/migrations/2019-02-26-002946_create_user/up.sql +++ b/migrations/2019-02-26-002946_create_user/up.sql @@ -1,23 +1,25 @@ -create table user_ ( - id serial primary key, - name varchar(20) not null, - fedi_name varchar(40) not null, - preferred_username varchar(20), - password_encrypted text not null, - email text unique, - icon bytea, - admin boolean default false not null, - banned boolean default false not null, - published timestamp not null default now(), - updated timestamp, - unique(name, fedi_name) +CREATE TABLE user_ ( + id serial PRIMARY KEY, + name varchar(20) NOT NULL, + fedi_name varchar(40) NOT NULL, + preferred_username varchar(20), + password_encrypted text NOT NULL, + email text UNIQUE, + icon bytea, + admin boolean DEFAULT FALSE NOT NULL, + banned boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp, + UNIQUE (name, fedi_name) ); -create table user_ban ( - id serial primary key, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique (user_id) +CREATE TABLE user_ban ( + id serial PRIMARY KEY, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (user_id) ); -insert into user_ (name, fedi_name, password_encrypted) values ('admin', 'TBD', 'TBD'); +INSERT INTO user_ (name, fedi_name, password_encrypted) + VALUES ('admin', 'TBD', 'TBD'); + diff --git a/migrations/2019-02-27-170003_create_community/down.sql b/migrations/2019-02-27-170003_create_community/down.sql index 219588d8..d5ecfc52 100644 --- a/migrations/2019-02-27-170003_create_community/down.sql +++ b/migrations/2019-02-27-170003_create_community/down.sql @@ -1,6 +1,14 @@ -drop table site; -drop table community_user_ban;; -drop table community_moderator; -drop table community_follower; -drop table community; -drop table category; +DROP TABLE site; + +DROP TABLE community_user_ban; + +; + +DROP TABLE community_moderator; + +DROP TABLE community_follower; + +DROP TABLE community; + +DROP TABLE category; + diff --git a/migrations/2019-02-27-170003_create_community/up.sql b/migrations/2019-02-27-170003_create_community/up.sql index 363f99f2..be851395 100644 --- a/migrations/2019-02-27-170003_create_community/up.sql +++ b/migrations/2019-02-27-170003_create_community/up.sql @@ -1,79 +1,81 @@ -create table category ( - id serial primary key, - name varchar(100) not null unique +CREATE TABLE category ( + id serial PRIMARY KEY, + name varchar(100) NOT NULL UNIQUE ); -insert into category (name) values -('Discussion'), -('Humor/Memes'), -('Gaming'), -('Movies'), -('TV'), -('Music'), -('Literature'), -('Comics'), -('Photography'), -('Art'), -('Learning'), -('DIY'), -('Lifestyle'), -('News'), -('Politics'), -('Society'), -('Gender/Identity/Sexuality'), -('Race/Colonisation'), -('Religion'), -('Science/Technology'), -('Programming/Software'), -('Health/Sports/Fitness'), -('Porn'), -('Places'), -('Meta'), -('Other'); +INSERT INTO category (name) + VALUES ('Discussion'), + ('Humor/Memes'), + ('Gaming'), + ('Movies'), + ('TV'), + ('Music'), + ('Literature'), + ('Comics'), + ('Photography'), + ('Art'), + ('Learning'), + ('DIY'), + ('Lifestyle'), + ('News'), + ('Politics'), + ('Society'), + ('Gender/Identity/Sexuality'), + ('Race/Colonisation'), + ('Religion'), + ('Science/Technology'), + ('Programming/Software'), + ('Health/Sports/Fitness'), + ('Porn'), + ('Places'), + ('Meta'), + ('Other'); -create table community ( - id serial primary key, - name varchar(20) not null unique, - title varchar(100) not null, - description text, - category_id int references category on update cascade on delete cascade not null, - creator_id int references user_ on update cascade on delete cascade not null, - removed boolean default false not null, - published timestamp not null default now(), - updated timestamp +CREATE TABLE community ( + id serial PRIMARY KEY, + name varchar(20) NOT NULL UNIQUE, + title varchar(100) NOT NULL, + description text, + category_id int REFERENCES category ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + removed boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); -create table community_moderator ( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique (community_id, user_id) +CREATE TABLE community_moderator ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (community_id, user_id) ); -create table community_follower ( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique (community_id, user_id) +CREATE TABLE community_follower ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (community_id, user_id) ); -create table community_user_ban ( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique (community_id, user_id) +CREATE TABLE community_user_ban ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (community_id, user_id) ); -insert into community (name, title, category_id, creator_id) values ('main', 'The Default Community', 1, 1); +INSERT INTO community (name, title, category_id, creator_id) + VALUES ('main', 'The Default Community', 1, 1); -create table site ( - id serial primary key, - name varchar(20) not null unique, - description text, - creator_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - updated timestamp +CREATE TABLE site ( + id serial PRIMARY KEY, + name varchar(20) NOT NULL UNIQUE, + description text, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); + diff --git a/migrations/2019-03-03-163336_create_post/down.sql b/migrations/2019-03-03-163336_create_post/down.sql index a671c2e7..193f1c1d 100644 --- a/migrations/2019-03-03-163336_create_post/down.sql +++ b/migrations/2019-03-03-163336_create_post/down.sql @@ -1,4 +1,8 @@ -drop table post_read; -drop table post_saved; -drop table post_like; -drop table post; +DROP TABLE post_read; + +DROP TABLE post_saved; + +DROP TABLE post_like; + +DROP TABLE post; + diff --git a/migrations/2019-03-03-163336_create_post/up.sql b/migrations/2019-03-03-163336_create_post/up.sql index 90737812..dfdd15c2 100644 --- a/migrations/2019-03-03-163336_create_post/up.sql +++ b/migrations/2019-03-03-163336_create_post/up.sql @@ -1,37 +1,38 @@ -create table post ( - id serial primary key, - name varchar(100) not null, - url text, -- These are both optional, a post can just have a title - body text, - creator_id int references user_ on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - removed boolean default false not null, - locked boolean default false not null, - published timestamp not null default now(), - updated timestamp +CREATE TABLE post ( + id serial PRIMARY KEY, + name varchar(100) NOT NULL, + url text, -- These are both optional, a post can just have a title + body text, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + removed boolean DEFAULT FALSE NOT NULL, + locked boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); -create table post_like ( - id serial primary key, - post_id int references post on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - score smallint not null, -- -1, or 1 for dislike, like, no row for no opinion - published timestamp not null default now(), - unique(post_id, user_id) +CREATE TABLE post_like ( + id serial PRIMARY KEY, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + score smallint NOT NULL, -- -1, or 1 for dislike, like, no row for no opinion + published timestamp NOT NULL DEFAULT now(), + UNIQUE (post_id, user_id) ); -create table post_saved ( - id serial primary key, - post_id int references post on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique(post_id, user_id) +CREATE TABLE post_saved ( + id serial PRIMARY KEY, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (post_id, user_id) ); -create table post_read ( - id serial primary key, - post_id int references post on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique(post_id, user_id) +CREATE TABLE post_read ( + id serial PRIMARY KEY, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (post_id, user_id) ); + diff --git a/migrations/2019-03-05-233828_create_comment/down.sql b/migrations/2019-03-05-233828_create_comment/down.sql index 80fe0b1f..4c4a13cd 100644 --- a/migrations/2019-03-05-233828_create_comment/down.sql +++ b/migrations/2019-03-05-233828_create_comment/down.sql @@ -1,3 +1,6 @@ -drop table comment_saved; -drop table comment_like; -drop table comment; +DROP TABLE comment_saved; + +DROP TABLE comment_like; + +DROP TABLE comment; + diff --git a/migrations/2019-03-05-233828_create_comment/up.sql b/migrations/2019-03-05-233828_create_comment/up.sql index 4b754ece..ed7ea17c 100644 --- a/migrations/2019-03-05-233828_create_comment/up.sql +++ b/migrations/2019-03-05-233828_create_comment/up.sql @@ -1,29 +1,30 @@ -create table comment ( - id serial primary key, - creator_id int references user_ on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - parent_id int references comment on update cascade on delete cascade, - content text not null, - removed boolean default false not null, - read boolean default false not null, - published timestamp not null default now(), - updated timestamp +CREATE TABLE comment ( + id serial PRIMARY KEY, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + parent_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE, + content text NOT NULL, + removed boolean DEFAULT FALSE NOT NULL, + read boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); -create table comment_like ( - id serial primary key, - user_id int references user_ on update cascade on delete cascade not null, - comment_id int references comment on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - score smallint not null, -- -1, or 1 for dislike, like, no row for no opinion - published timestamp not null default now(), - unique(comment_id, user_id) +CREATE TABLE comment_like ( + id serial PRIMARY KEY, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + score smallint NOT NULL, -- -1, or 1 for dislike, like, no row for no opinion + published timestamp NOT NULL DEFAULT now(), + UNIQUE (comment_id, user_id) ); -create table comment_saved ( - id serial primary key, - comment_id int references comment on update cascade on delete cascade not null, - user_id int references user_ on update cascade on delete cascade not null, - published timestamp not null default now(), - unique(comment_id, user_id) +CREATE TABLE comment_saved ( + id serial PRIMARY KEY, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (comment_id, user_id) ); + diff --git a/migrations/2019-03-30-212058_create_post_view/down.sql b/migrations/2019-03-30-212058_create_post_view/down.sql index 37c54d91..75f9dc99 100644 --- a/migrations/2019-03-30-212058_create_post_view/down.sql +++ b/migrations/2019-03-30-212058_create_post_view/down.sql @@ -1,2 +1,4 @@ -drop view post_view; -drop function hot_rank; +DROP VIEW post_view; + +DROP FUNCTION hot_rank; + diff --git a/migrations/2019-03-30-212058_create_post_view/up.sql b/migrations/2019-03-30-212058_create_post_view/up.sql index 4a4fd146..7b5a8574 100644 --- a/migrations/2019-03-30-212058_create_post_view/up.sql +++ b/migrations/2019-03-30-212058_create_post_view/up.sql @@ -1,51 +1,107 @@ -- Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity -create or replace function hot_rank( - score numeric, - published timestamp without time zone) -returns integer as $$ -begin - -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 - return floor(10000*log(greatest(1,score+3)) / power(((EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600) + 2), 1.8))::integer; -end; $$ +CREATE OR REPLACE FUNCTION hot_rank (score numeric, published timestamp without time zone) + RETURNS integer + AS $$ +BEGIN + -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 + RETURN floor(10000 * log(greatest (1, score + 3)) / power(((EXTRACT(EPOCH FROM (timezone('utc', now()) - published)) / 3600) + 2), 1.8))::integer; +END; +$$ LANGUAGE plpgsql; -create view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id ) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-04-03-155205_create_community_view/down.sql b/migrations/2019-04-03-155205_create_community_view/down.sql index 67d12f6f..494b8257 100644 --- a/migrations/2019-04-03-155205_create_community_view/down.sql +++ b/migrations/2019-04-03-155205_create_community_view/down.sql @@ -1,5 +1,10 @@ -drop view community_view; -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view site_view; +DROP VIEW community_view; + +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW site_view; + diff --git a/migrations/2019-04-03-155205_create_community_view/up.sql b/migrations/2019-04-03-155205_create_community_view/up.sql index 7d38dbfa..7f86e38a 100644 --- a/migrations/2019-04-03-155205_create_community_view/up.sql +++ b/migrations/2019-04-03-155205_create_community_view/up.sql @@ -1,53 +1,154 @@ -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments - from community c +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments + FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +CREATE VIEW community_moderator_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_moderator cm; -union all +CREATE VIEW community_follower_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cf.community_id = c.id) AS community_name +FROM + community_follower cf; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +CREATE VIEW community_user_ban_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_user_ban cm; -create view community_moderator_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select name from community c where cm.community_id = c.id) as community_name -from community_moderator cm; +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments +FROM + site s; -create view community_follower_view as -select *, -(select name from user_ u where cf.user_id = u.id) as user_name, -(select name from community c where cf.community_id = c.id) as community_name -from community_follower cf; - -create view community_user_ban_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select name from community c where cm.community_id = c.id) as community_name -from community_user_ban cm; - -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments -from site s; diff --git a/migrations/2019-04-03-155309_create_comment_view/down.sql b/migrations/2019-04-03-155309_create_comment_view/down.sql index c19d5ff7..22313223 100644 --- a/migrations/2019-04-03-155309_create_comment_view/down.sql +++ b/migrations/2019-04-03-155309_create_comment_view/down.sql @@ -1,2 +1,4 @@ -drop view reply_view; -drop view comment_view; +DROP VIEW reply_view; + +DROP VIEW comment_view; + diff --git a/migrations/2019-04-03-155309_create_comment_view/up.sql b/migrations/2019-04-03-155309_create_comment_view/up.sql index 24ce98fc..dee4b97b 100644 --- a/migrations/2019-04-03-155309_create_comment_view/up.sql +++ b/migrations/2019-04-03-155309_create_comment_view/up.sql @@ -1,60 +1,114 @@ -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id ) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; diff --git a/migrations/2019-04-07-003142_create_moderation_logs/down.sql b/migrations/2019-04-07-003142_create_moderation_logs/down.sql index 888a87fe..aa2fd815 100644 --- a/migrations/2019-04-07-003142_create_moderation_logs/down.sql +++ b/migrations/2019-04-07-003142_create_moderation_logs/down.sql @@ -1,8 +1,16 @@ -drop table mod_remove_post; -drop table mod_lock_post; -drop table mod_remove_comment; -drop table mod_remove_community; -drop table mod_ban; -drop table mod_ban_from_community; -drop table mod_add; -drop table mod_add_community; +DROP TABLE mod_remove_post; + +DROP TABLE mod_lock_post; + +DROP TABLE mod_remove_comment; + +DROP TABLE mod_remove_community; + +DROP TABLE mod_ban; + +DROP TABLE mod_ban_from_community; + +DROP TABLE mod_add; + +DROP TABLE mod_add_community; + diff --git a/migrations/2019-04-07-003142_create_moderation_logs/up.sql b/migrations/2019-04-07-003142_create_moderation_logs/up.sql index 3b320d81..718723c9 100644 --- a/migrations/2019-04-07-003142_create_moderation_logs/up.sql +++ b/migrations/2019-04-07-003142_create_moderation_logs/up.sql @@ -1,76 +1,76 @@ -create table mod_remove_post ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - reason text, - removed boolean default true, - when_ timestamp not null default now() +CREATE TABLE mod_remove_post ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + removed boolean DEFAULT TRUE, + when_ timestamp NOT NULL DEFAULT now() ); -create table mod_lock_post ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - locked boolean default true, - when_ timestamp not null default now() +CREATE TABLE mod_lock_post ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + locked boolean DEFAULT TRUE, + when_ timestamp NOT NULL DEFAULT now() ); -create table mod_remove_comment ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - comment_id int references comment on update cascade on delete cascade not null, - reason text, - removed boolean default true, - when_ timestamp not null default now() +CREATE TABLE mod_remove_comment ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + removed boolean DEFAULT TRUE, + when_ timestamp NOT NULL DEFAULT now() ); -create table mod_remove_community ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - reason text, - removed boolean default true, - expires timestamp, - when_ timestamp not null default now() +CREATE TABLE mod_remove_community ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + removed boolean DEFAULT TRUE, + expires timestamp, + when_ timestamp NOT NULL DEFAULT now() ); -- TODO make sure you can't ban other mods -create table mod_ban_from_community ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - other_user_id int references user_ on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - reason text, - banned boolean default true, - expires timestamp, - when_ timestamp not null default now() +CREATE TABLE mod_ban_from_community ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + other_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + banned boolean DEFAULT TRUE, + expires timestamp, + when_ timestamp NOT NULL DEFAULT now() ); -create table mod_ban ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - other_user_id int references user_ on update cascade on delete cascade not null, - reason text, - banned boolean default true, - expires timestamp, - when_ timestamp not null default now() +CREATE TABLE mod_ban ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + other_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + banned boolean DEFAULT TRUE, + expires timestamp, + when_ timestamp NOT NULL DEFAULT now() ); -create table mod_add_community ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - other_user_id int references user_ on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - removed boolean default false, - when_ timestamp not null default now() +CREATE TABLE mod_add_community ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + other_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + removed boolean DEFAULT FALSE, + when_ timestamp NOT NULL DEFAULT now() ); -- When removed is false that means kicked -create table mod_add ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - other_user_id int references user_ on update cascade on delete cascade not null, - removed boolean default false, - when_ timestamp not null default now() +CREATE TABLE mod_add ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + other_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + removed boolean DEFAULT FALSE, + when_ timestamp NOT NULL DEFAULT now() ); diff --git a/migrations/2019-04-08-015947_create_user_view/down.sql b/migrations/2019-04-08-015947_create_user_view/down.sql index c94d94c4..eec12284 100644 --- a/migrations/2019-04-08-015947_create_user_view/down.sql +++ b/migrations/2019-04-08-015947_create_user_view/down.sql @@ -1 +1,2 @@ -drop view user_view; +DROP VIEW user_view; + diff --git a/migrations/2019-04-08-015947_create_user_view/up.sql b/migrations/2019-04-08-015947_create_user_view/up.sql index 08eb56ca..a6590593 100644 --- a/migrations/2019-04-08-015947_create_user_view/up.sql +++ b/migrations/2019-04-08-015947_create_user_view/up.sql @@ -1,12 +1,43 @@ -create view user_view as -select id, -name, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +CREATE VIEW user_view AS +SELECT + id, + name, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + diff --git a/migrations/2019-04-11-144915_create_mod_views/down.sql b/migrations/2019-04-11-144915_create_mod_views/down.sql index 95018f35..bf3b8bbf 100644 --- a/migrations/2019-04-11-144915_create_mod_views/down.sql +++ b/migrations/2019-04-11-144915_create_mod_views/down.sql @@ -1,8 +1,16 @@ -drop view mod_remove_post_view; -drop view mod_lock_post_view; -drop view mod_remove_comment_view; -drop view mod_remove_community_view; -drop view mod_ban_from_community_view; -drop view mod_ban_view; -drop view mod_add_community_view; -drop view mod_add_view; +DROP VIEW mod_remove_post_view; + +DROP VIEW mod_lock_post_view; + +DROP VIEW mod_remove_comment_view; + +DROP VIEW mod_remove_community_view; + +DROP VIEW mod_ban_from_community_view; + +DROP VIEW mod_ban_view; + +DROP VIEW mod_add_community_view; + +DROP VIEW mod_add_view; + diff --git a/migrations/2019-04-11-144915_create_mod_views/up.sql b/migrations/2019-04-11-144915_create_mod_views/up.sql index 70a33e46..b252a4ba 100644 --- a/migrations/2019-04-11-144915_create_mod_views/up.sql +++ b/migrations/2019-04-11-144915_create_mod_views/up.sql @@ -1,59 +1,266 @@ -create view mod_remove_post_view as -select mrp.*, -(select name from user_ u where mrp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mrp.post_id = p.id) as post_name, -(select c.id from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_name -from mod_remove_post mrp; - -create view mod_lock_post_view as -select mlp.*, -(select name from user_ u where mlp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mlp.post_id = p.id) as post_name, -(select c.id from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_name -from mod_lock_post mlp; - -create view mod_remove_comment_view as -select mrc.*, -(select name from user_ u where mrc.mod_user_id = u.id) as mod_user_name, -(select c.id from comment c where mrc.comment_id = c.id) as comment_user_id, -(select name from user_ u, comment c where mrc.comment_id = c.id and u.id = c.creator_id) as comment_user_name, -(select content from comment c where mrc.comment_id = c.id) as comment_content, -(select p.id from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_id, -(select p.name from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_name, -(select co.id from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_id, -(select co.name from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_name -from mod_remove_comment mrc; - -create view mod_remove_community_view as -select mrc.*, -(select name from user_ u where mrc.mod_user_id = u.id) as mod_user_name, -(select c.name from community c where mrc.community_id = c.id) as community_name -from mod_remove_community mrc; - -create view mod_ban_from_community_view as -select mb.*, -(select name from user_ u where mb.mod_user_id = u.id) as mod_user_name, -(select name from user_ u where mb.other_user_id = u.id) as other_user_name, -(select name from community c where mb.community_id = c.id) as community_name -from mod_ban_from_community mb; - -create view mod_ban_view as -select mb.*, -(select name from user_ u where mb.mod_user_id = u.id) as mod_user_name, -(select name from user_ u where mb.other_user_id = u.id) as other_user_name -from mod_ban mb; - -create view mod_add_community_view as -select ma.*, -(select name from user_ u where ma.mod_user_id = u.id) as mod_user_name, -(select name from user_ u where ma.other_user_id = u.id) as other_user_name, -(select name from community c where ma.community_id = c.id) as community_name -from mod_add_community ma; - -create view mod_add_view as -select ma.*, -(select name from user_ u where ma.mod_user_id = u.id) as mod_user_name, -(select name from user_ u where ma.other_user_id = u.id) as other_user_name -from mod_add ma; +CREATE VIEW mod_remove_post_view AS +SELECT + mrp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mrp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_remove_post mrp; + +CREATE VIEW mod_lock_post_view AS +SELECT + mlp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mlp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mlp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_lock_post mlp; + +CREATE VIEW mod_remove_comment_view AS +SELECT + mrc.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrc.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + c.id + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_user_id, + ( + SELECT + name + FROM + user_ u, + comment c + WHERE + mrc.comment_id = c.id + AND u.id = c.creator_id) AS comment_user_name, + ( + SELECT + content + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_content, + ( + SELECT + p.id + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_id, + ( + SELECT + p.name + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_name, + ( + SELECT + co.id + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_id, + ( + SELECT + co.name + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_name +FROM + mod_remove_comment mrc; + +CREATE VIEW mod_remove_community_view AS +SELECT + mrc.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrc.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + c.name + FROM + community c + WHERE + mrc.community_id = c.id) AS community_name +FROM + mod_remove_community mrc; + +CREATE VIEW mod_ban_from_community_view AS +SELECT + mb.*, + ( + SELECT + name + FROM + user_ u + WHERE + mb.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + user_ u + WHERE + mb.other_user_id = u.id) AS other_user_name, + ( + SELECT + name + FROM + community c + WHERE + mb.community_id = c.id) AS community_name +FROM + mod_ban_from_community mb; + +CREATE VIEW mod_ban_view AS +SELECT + mb.*, + ( + SELECT + name + FROM + user_ u + WHERE + mb.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + user_ u + WHERE + mb.other_user_id = u.id) AS other_user_name +FROM + mod_ban mb; + +CREATE VIEW mod_add_community_view AS +SELECT + ma.*, + ( + SELECT + name + FROM + user_ u + WHERE + ma.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + user_ u + WHERE + ma.other_user_id = u.id) AS other_user_name, + ( + SELECT + name + FROM + community c + WHERE + ma.community_id = c.id) AS community_name +FROM + mod_add_community ma; + +CREATE VIEW mod_add_view AS +SELECT + ma.*, + ( + SELECT + name + FROM + user_ u + WHERE + ma.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + user_ u + WHERE + ma.other_user_id = u.id) AS other_user_name +FROM + mod_add ma; + diff --git a/migrations/2019-04-29-175834_add_delete_columns/down.sql b/migrations/2019-04-29-175834_add_delete_columns/down.sql index 5e13295b..2cb9fda3 100644 --- a/migrations/2019-04-29-175834_add_delete_columns/down.sql +++ b/migrations/2019-04-29-175834_add_delete_columns/down.sql @@ -1,137 +1,293 @@ -drop view reply_view; -drop view comment_view; -drop view community_view; -drop view post_view; -alter table community drop column deleted; -alter table post drop column deleted; -alter table comment drop column deleted; +DROP VIEW reply_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments - from community c -) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +DROP VIEW comment_view; -union all +DROP VIEW community_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +DROP VIEW post_view; -create or replace view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) +ALTER TABLE community + DROP COLUMN deleted; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +ALTER TABLE post + DROP COLUMN deleted; -union all +ALTER TABLE comment + DROP COLUMN deleted; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments + FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all +CREATE OR REPLACE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id +) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; diff --git a/migrations/2019-04-29-175834_add_delete_columns/up.sql b/migrations/2019-04-29-175834_add_delete_columns/up.sql index 88432dda..05ac1389 100644 --- a/migrations/2019-04-29-175834_add_delete_columns/up.sql +++ b/migrations/2019-04-29-175834_add_delete_columns/up.sql @@ -1,141 +1,301 @@ -alter table community add column deleted boolean default false not null; -alter table post add column deleted boolean default false not null; -alter table comment add column deleted boolean default false not null; +ALTER TABLE community + ADD COLUMN deleted boolean DEFAULT FALSE NOT NULL; --- The views -drop view community_view; - -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments - from community c -) +ALTER TABLE post + ADD COLUMN deleted boolean DEFAULT FALSE NOT NULL; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +ALTER TABLE comment + ADD COLUMN deleted boolean DEFAULT FALSE NOT NULL; +-- The views +DROP VIEW community_view; -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments + FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +DROP VIEW post_view; -drop view reply_view; -drop view comment_view; -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id ) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW reply_view; -union all +DROP VIEW comment_view; -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id +) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; diff --git a/migrations/2019-05-02-051656_community_view_hot_rank/down.sql b/migrations/2019-05-02-051656_community_view_hot_rank/down.sql index 0f3a58a8..7d3af250 100644 --- a/migrations/2019-05-02-051656_community_view_hot_rank/down.sql +++ b/migrations/2019-05-02-051656_community_view_hot_rank/down.sql @@ -1,28 +1,68 @@ -drop view community_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments - from community c -) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +DROP VIEW community_view; -union all +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments + FROM + community c +) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; diff --git a/migrations/2019-05-02-051656_community_view_hot_rank/up.sql b/migrations/2019-05-02-051656_community_view_hot_rank/up.sql index e7e75366..fdd79e4c 100644 --- a/migrations/2019-05-02-051656_community_view_hot_rank/up.sql +++ b/migrations/2019-05-02-051656_community_view_hot_rank/up.sql @@ -1,29 +1,74 @@ -drop view community_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c -) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +DROP VIEW community_view; -union all +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c +) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; diff --git a/migrations/2019-06-01-222649_remove_admin/down.sql b/migrations/2019-06-01-222649_remove_admin/down.sql index 6178857f..926c18af 100644 --- a/migrations/2019-06-01-222649_remove_admin/down.sql +++ b/migrations/2019-06-01-222649_remove_admin/down.sql @@ -1 +1,3 @@ -insert into user_ (name, fedi_name, password_encrypted) values ('admin', 'TBD', 'TBD'); +INSERT INTO user_ (name, fedi_name, password_encrypted) + VALUES ('admin', 'TBD', 'TBD'); + diff --git a/migrations/2019-06-01-222649_remove_admin/up.sql b/migrations/2019-06-01-222649_remove_admin/up.sql index 7cec8870..cf3d20d4 100644 --- a/migrations/2019-06-01-222649_remove_admin/up.sql +++ b/migrations/2019-06-01-222649_remove_admin/up.sql @@ -1 +1,3 @@ -delete from user_ where name like 'admin'; +DELETE FROM user_ +WHERE name LIKE 'admin'; + diff --git a/migrations/2019-08-11-000918_add_nsfw_columns/down.sql b/migrations/2019-08-11-000918_add_nsfw_columns/down.sql index 2eefece4..12c46b7f 100644 --- a/migrations/2019-08-11-000918_add_nsfw_columns/down.sql +++ b/migrations/2019-08-11-000918_add_nsfw_columns/down.sql @@ -1,80 +1,190 @@ -drop view community_view; -drop view post_view; -alter table community drop column nsfw; -alter table post drop column nsfw; -alter table user_ drop column show_nsfw; +DROP VIEW community_view; --- the views -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c -) +DROP VIEW post_view; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +ALTER TABLE community + DROP COLUMN nsfw; -union all +ALTER TABLE post + DROP COLUMN nsfw; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +ALTER TABLE user_ + DROP COLUMN show_nsfw; +-- the views +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c +) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -- Post view -create view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id ) - -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; diff --git a/migrations/2019-08-11-000918_add_nsfw_columns/up.sql b/migrations/2019-08-11-000918_add_nsfw_columns/up.sql index cc1e0074..a4371818 100644 --- a/migrations/2019-08-11-000918_add_nsfw_columns/up.sql +++ b/migrations/2019-08-11-000918_add_nsfw_columns/up.sql @@ -1,79 +1,197 @@ -alter table community add column nsfw boolean default false not null; -alter table post add column nsfw boolean default false not null; -alter table user_ add column show_nsfw boolean default false not null; +ALTER TABLE community + ADD COLUMN nsfw boolean DEFAULT FALSE NOT NULL; --- The views -drop view community_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c -) +ALTER TABLE post + ADD COLUMN nsfw boolean DEFAULT FALSE NOT NULL; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +ALTER TABLE user_ + ADD COLUMN show_nsfw boolean DEFAULT FALSE NOT NULL; -union all +-- The views +DROP VIEW community_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - --- Post view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +-- Post view +DROP VIEW post_view; -union all +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-08-29-040006_add_community_count/down.sql b/migrations/2019-08-29-040006_add_community_count/down.sql index 6302f267..a016508f 100644 --- a/migrations/2019-08-29-040006_add_community_count/down.sql +++ b/migrations/2019-08-29-040006_add_community_count/down.sql @@ -1,9 +1,30 @@ -drop view site_view; +DROP VIEW site_view; + +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments +FROM + site s; -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments -from site s; diff --git a/migrations/2019-08-29-040006_add_community_count/up.sql b/migrations/2019-08-29-040006_add_community_count/up.sql index 0ec1c9c3..9747ac84 100644 --- a/migrations/2019-08-29-040006_add_community_count/up.sql +++ b/migrations/2019-08-29-040006_add_community_count/up.sql @@ -1,10 +1,35 @@ -drop view site_view; +DROP VIEW site_view; + +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; diff --git a/migrations/2019-09-05-230317_add_mod_ban_views/down.sql b/migrations/2019-09-05-230317_add_mod_ban_views/down.sql index c60b672c..2b5782e0 100644 --- a/migrations/2019-09-05-230317_add_mod_ban_views/down.sql +++ b/migrations/2019-09-05-230317_add_mod_ban_views/down.sql @@ -1,44 +1,113 @@ -- Post view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) - -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +DROP VIEW post_view; -union all +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-09-05-230317_add_mod_ban_views/up.sql b/migrations/2019-09-05-230317_add_mod_ban_views/up.sql index d73b3720..94fc5754 100644 --- a/migrations/2019-09-05-230317_add_mod_ban_views/up.sql +++ b/migrations/2019-09-05-230317_add_mod_ban_views/up.sql @@ -1,47 +1,128 @@ --- Create post view, adding banned_from_community +-- Create post view, adding banned_from_community +DROP VIEW post_view; -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id ) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-09-09-042010_add_stickied_posts/down.sql b/migrations/2019-09-09-042010_add_stickied_posts/down.sql index fb8eac8f..838959b3 100644 --- a/migrations/2019-09-09-042010_add_stickied_posts/down.sql +++ b/migrations/2019-09-09-042010_add_stickied_posts/down.sql @@ -1,50 +1,134 @@ -drop view post_view; -drop view mod_sticky_post_view; -alter table post drop column stickied; +DROP VIEW post_view; -drop table mod_sticky_post; +DROP VIEW mod_sticky_post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) +ALTER TABLE post + DROP COLUMN stickied; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +DROP TABLE mod_sticky_post; -union all +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-09-09-042010_add_stickied_posts/up.sql b/migrations/2019-09-09-042010_add_stickied_posts/up.sql index 0848f86c..555d2874 100644 --- a/migrations/2019-09-09-042010_add_stickied_posts/up.sql +++ b/migrations/2019-09-09-042010_add_stickied_posts/up.sql @@ -1,67 +1,180 @@ -- Add the column -alter table post add column stickied boolean default false not null; +ALTER TABLE post + ADD COLUMN stickied boolean DEFAULT FALSE NOT NULL; -- Add the mod table -create table mod_sticky_post ( - id serial primary key, - mod_user_id int references user_ on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - stickied boolean default true, - when_ timestamp not null default now() +CREATE TABLE mod_sticky_post ( + id serial PRIMARY KEY, + mod_user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + stickied boolean DEFAULT TRUE, + when_ timestamp NOT NULL DEFAULT now() ); -- Add mod view -create view mod_sticky_post_view as -select msp.*, -(select name from user_ u where msp.mod_user_id = u.id) as mod_user_name, -(select name from post p where msp.post_id = p.id) as post_name, -(select c.id from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_name -from mod_sticky_post msp; +CREATE VIEW mod_sticky_post_view AS +SELECT + msp.*, + ( + SELECT + name + FROM + user_ u + WHERE + msp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + msp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_sticky_post msp; -- Recreate the view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) - -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +DROP VIEW post_view; -union all +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; diff --git a/migrations/2019-10-15-181630_add_themes/down.sql b/migrations/2019-10-15-181630_add_themes/down.sql index 67a5e17b..a3106302 100644 --- a/migrations/2019-10-15-181630_add_themes/down.sql +++ b/migrations/2019-10-15-181630_add_themes/down.sql @@ -1 +1,3 @@ -alter table user_ drop column theme; +ALTER TABLE user_ + DROP COLUMN theme; + diff --git a/migrations/2019-10-15-181630_add_themes/up.sql b/migrations/2019-10-15-181630_add_themes/up.sql index e9c3666b..00b3d10a 100644 --- a/migrations/2019-10-15-181630_add_themes/up.sql +++ b/migrations/2019-10-15-181630_add_themes/up.sql @@ -1 +1,3 @@ -alter table user_ add column theme varchar(20) default 'darkly' not null; +ALTER TABLE user_ + ADD COLUMN theme varchar(20) DEFAULT 'darkly' NOT NULL; + diff --git a/migrations/2019-10-19-052737_create_user_mention/down.sql b/migrations/2019-10-19-052737_create_user_mention/down.sql index 7165bc86..e21425c5 100644 --- a/migrations/2019-10-19-052737_create_user_mention/down.sql +++ b/migrations/2019-10-19-052737_create_user_mention/down.sql @@ -1,2 +1,4 @@ -drop view user_mention_view; -drop table user_mention; +DROP VIEW user_mention_view; + +DROP TABLE user_mention; + diff --git a/migrations/2019-10-19-052737_create_user_mention/up.sql b/migrations/2019-10-19-052737_create_user_mention/up.sql index 81fef008..b02c5752 100644 --- a/migrations/2019-10-19-052737_create_user_mention/up.sql +++ b/migrations/2019-10-19-052737_create_user_mention/up.sql @@ -1,16 +1,16 @@ -create table user_mention ( - id serial primary key, - recipient_id int references user_ on update cascade on delete cascade not null, - comment_id int references comment on update cascade on delete cascade not null, - read boolean default false not null, - published timestamp not null default now(), - unique(recipient_id, comment_id) +CREATE TABLE user_mention ( + id serial PRIMARY KEY, + recipient_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + read boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (recipient_id, comment_id) ); -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -31,5 +31,9 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + diff --git a/migrations/2019-10-21-011237_add_default_sorts/down.sql b/migrations/2019-10-21-011237_add_default_sorts/down.sql index 238c9e79..3763b5a0 100644 --- a/migrations/2019-10-21-011237_add_default_sorts/down.sql +++ b/migrations/2019-10-21-011237_add_default_sorts/down.sql @@ -1,2 +1,6 @@ -alter table user_ drop column default_sort_type; -alter table user_ drop column default_listing_type; +ALTER TABLE user_ + DROP COLUMN default_sort_type; + +ALTER TABLE user_ + DROP COLUMN default_listing_type; + diff --git a/migrations/2019-10-21-011237_add_default_sorts/up.sql b/migrations/2019-10-21-011237_add_default_sorts/up.sql index 4bb96009..62d04141 100644 --- a/migrations/2019-10-21-011237_add_default_sorts/up.sql +++ b/migrations/2019-10-21-011237_add_default_sorts/up.sql @@ -1,2 +1,6 @@ -alter table user_ add column default_sort_type smallint default 0 not null; -alter table user_ add column default_listing_type smallint default 1 not null; +ALTER TABLE user_ + ADD COLUMN default_sort_type smallint DEFAULT 0 NOT NULL; + +ALTER TABLE user_ + ADD COLUMN default_listing_type smallint DEFAULT 1 NOT NULL; + diff --git a/migrations/2019-10-24-002614_create_password_reset_request/down.sql b/migrations/2019-10-24-002614_create_password_reset_request/down.sql index 33500dfe..54d4ba82 100644 --- a/migrations/2019-10-24-002614_create_password_reset_request/down.sql +++ b/migrations/2019-10-24-002614_create_password_reset_request/down.sql @@ -1 +1,2 @@ -drop table password_reset_request; +DROP TABLE password_reset_request; + diff --git a/migrations/2019-10-24-002614_create_password_reset_request/up.sql b/migrations/2019-10-24-002614_create_password_reset_request/up.sql index 15cfaa59..f883d150 100644 --- a/migrations/2019-10-24-002614_create_password_reset_request/up.sql +++ b/migrations/2019-10-24-002614_create_password_reset_request/up.sql @@ -1,6 +1,7 @@ -create table password_reset_request ( - id serial primary key, - user_id int references user_ on update cascade on delete cascade not null, - token_encrypted text not null, - published timestamp not null default now() +CREATE TABLE password_reset_request ( + id serial PRIMARY KEY, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + token_encrypted text NOT NULL, + published timestamp NOT NULL DEFAULT now() ); + diff --git a/migrations/2019-12-09-060754_add_lang/down.sql b/migrations/2019-12-09-060754_add_lang/down.sql index c1335599..eb64acf8 100644 --- a/migrations/2019-12-09-060754_add_lang/down.sql +++ b/migrations/2019-12-09-060754_add_lang/down.sql @@ -1 +1,3 @@ -alter table user_ drop column lang; +ALTER TABLE user_ + DROP COLUMN lang; + diff --git a/migrations/2019-12-09-060754_add_lang/up.sql b/migrations/2019-12-09-060754_add_lang/up.sql index 98a72ad9..a1279da6 100644 --- a/migrations/2019-12-09-060754_add_lang/up.sql +++ b/migrations/2019-12-09-060754_add_lang/up.sql @@ -1 +1,3 @@ -alter table user_ add column lang varchar(20) default 'browser' not null; +ALTER TABLE user_ + ADD COLUMN lang varchar(20) DEFAULT 'browser' NOT NULL; + diff --git a/migrations/2019-12-11-181820_add_site_fields/down.sql b/migrations/2019-12-11-181820_add_site_fields/down.sql index 72eedba4..107d2256 100644 --- a/migrations/2019-12-11-181820_add_site_fields/down.sql +++ b/migrations/2019-12-11-181820_add_site_fields/down.sql @@ -1,16 +1,46 @@ -- Drop the columns -drop view site_view; -alter table site drop column enable_downvotes; -alter table site drop column open_registration; -alter table site drop column enable_nsfw; +DROP VIEW site_view; + +ALTER TABLE site + DROP COLUMN enable_downvotes; + +ALTER TABLE site + DROP COLUMN open_registration; + +ALTER TABLE site + DROP COLUMN enable_nsfw; -- Rebuild the views +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; diff --git a/migrations/2019-12-11-181820_add_site_fields/up.sql b/migrations/2019-12-11-181820_add_site_fields/up.sql index e107b1ac..319aca2d 100644 --- a/migrations/2019-12-11-181820_add_site_fields/up.sql +++ b/migrations/2019-12-11-181820_add_site_fields/up.sql @@ -1,16 +1,46 @@ -- Add the column -alter table site add column enable_downvotes boolean default true not null; -alter table site add column open_registration boolean default true not null; -alter table site add column enable_nsfw boolean default true not null; +ALTER TABLE site + ADD COLUMN enable_downvotes boolean DEFAULT TRUE NOT NULL; + +ALTER TABLE site + ADD COLUMN open_registration boolean DEFAULT TRUE NOT NULL; + +ALTER TABLE site + ADD COLUMN enable_nsfw boolean DEFAULT TRUE NOT NULL; -- Reload the view -drop view site_view; +DROP VIEW site_view; + +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; diff --git a/migrations/2019-12-29-164820_add_avatar/down.sql b/migrations/2019-12-29-164820_add_avatar/down.sql index 74b4146d..bd062b53 100644 --- a/migrations/2019-12-29-164820_add_avatar/down.sql +++ b/migrations/2019-12-29-164820_add_avatar/down.sql @@ -1,169 +1,380 @@ -- the views -drop view user_mention_view; -drop view reply_view; -drop view comment_view; -drop view user_view; +DROP VIEW user_mention_view; + +DROP VIEW reply_view; + +DROP VIEW comment_view; + +DROP VIEW user_view; -- user -create view user_view as -select id, -name, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +CREATE VIEW user_view AS +SELECT + id, + name, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -- post -- Recreate the view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) +DROP VIEW post_view; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- community +DROP VIEW community_view; -drop view community_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c ) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -- Reply and comment view -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id ) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -184,41 +395,117 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -- community tables -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view site_view; - -create view community_moderator_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select name from community c where cm.community_id = c.id) as community_name -from community_moderator cm; - -create view community_follower_view as -select *, -(select name from user_ u where cf.user_id = u.id) as user_name, -(select name from community c where cf.community_id = c.id) as community_name -from community_follower cf; - -create view community_user_ban_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select name from community c where cm.community_id = c.id) as community_name -from community_user_ban cm; - -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; - -alter table user_ rename column avatar to icon; -alter table user_ alter column icon type bytea using icon::bytea; +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW site_view; + +CREATE VIEW community_moderator_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_moderator cm; + +CREATE VIEW community_follower_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cf.community_id = c.id) AS community_name +FROM + community_follower cf; + +CREATE VIEW community_user_ban_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_user_ban cm; + +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; + +ALTER TABLE user_ RENAME COLUMN avatar TO icon; + +ALTER TABLE user_ + ALTER COLUMN icon TYPE bytea + USING icon::bytea; + diff --git a/migrations/2019-12-29-164820_add_avatar/up.sql b/migrations/2019-12-29-164820_add_avatar/up.sql index f9265154..79bf2cc5 100644 --- a/migrations/2019-12-29-164820_add_avatar/up.sql +++ b/migrations/2019-12-29-164820_add_avatar/up.sql @@ -1,177 +1,408 @@ -- Rename to avatar -alter table user_ rename column icon to avatar; -alter table user_ alter column avatar type text; +ALTER TABLE user_ RENAME COLUMN icon TO avatar; --- Rebuild nearly all the views, to include the creator avatars +ALTER TABLE user_ + ALTER COLUMN avatar TYPE text; +-- Rebuild nearly all the views, to include the creator avatars -- user -drop view user_view; -create view user_view as -select id, -name, -avatar, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -- post -- Recreate the view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select avatar from user_ where p.creator_id = user_.id) as creator_avatar, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id -) - -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +DROP VIEW post_view; +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- community -drop view community_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select avatar from user_ u where c.creator_id = u.id) as creator_avatar, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c +DROP VIEW community_view; + +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +-- reply and comment view +DROP VIEW reply_view; -union all +DROP VIEW user_mention_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +DROP VIEW comment_view; --- reply and comment view -drop view reply_view; -drop view user_mention_view; -drop view comment_view; -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - (select avatar from user_ where c.creator_id = user_.id) as creator_avatar, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id ) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -193,42 +424,136 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -- community views -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view site_view; - -create view community_moderator_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select name from community c where cm.community_id = c.id) as community_name -from community_moderator cm; - -create view community_follower_view as -select *, -(select name from user_ u where cf.user_id = u.id) as user_name, -(select avatar from user_ u where cf.user_id = u.id), -(select name from community c where cf.community_id = c.id) as community_name -from community_follower cf; - -create view community_user_ban_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select name from community c where cm.community_id = c.id) as community_name -from community_user_ban cm; - -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select avatar from user_ u where s.creator_id = u.id) as creator_avatar, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW site_view; + +CREATE VIEW community_moderator_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_moderator cm; + +CREATE VIEW community_follower_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cf.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cf.community_id = c.id) AS community_name +FROM + community_follower cf; + +CREATE VIEW community_user_ban_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_user_ban cm; + +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_avatar, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; + diff --git a/migrations/2020-01-01-200418_add_email_to_user_view/down.sql b/migrations/2020-01-01-200418_add_email_to_user_view/down.sql index 92f771f8..759623c7 100644 --- a/migrations/2020-01-01-200418_add_email_to_user_view/down.sql +++ b/migrations/2020-01-01-200418_add_email_to_user_view/down.sql @@ -1,15 +1,47 @@ -- user -drop view user_view; -create view user_view as -select id, -name, -avatar, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + diff --git a/migrations/2020-01-01-200418_add_email_to_user_view/up.sql b/migrations/2020-01-01-200418_add_email_to_user_view/up.sql index 59972dfb..d1a319e7 100644 --- a/migrations/2020-01-01-200418_add_email_to_user_view/up.sql +++ b/migrations/2020-01-01-200418_add_email_to_user_view/up.sql @@ -1,16 +1,48 @@ -- user -drop view user_view; -create view user_view as -select id, -name, -avatar, -email, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + email, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + diff --git a/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql b/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql index ec061223..517e2b30 100644 --- a/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql +++ b/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql @@ -1,20 +1,55 @@ -- Drop the columns -drop view user_view; -alter table user_ drop column show_avatars; -alter table user_ drop column send_notifications_to_email; +DROP VIEW user_view; + +ALTER TABLE user_ + DROP COLUMN show_avatars; + +ALTER TABLE user_ + DROP COLUMN send_notifications_to_email; -- Rebuild the view -create view user_view as -select id, -name, -avatar, -email, -fedi_name, -admin, -banned, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + email, + fedi_name, + admin, + banned, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + diff --git a/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql b/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql index 21f0aff4..661907d2 100644 --- a/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql +++ b/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql @@ -1,22 +1,57 @@ -- Add columns -alter table user_ add column show_avatars boolean default true not null; -alter table user_ add column send_notifications_to_email boolean default false not null; +ALTER TABLE user_ + ADD COLUMN show_avatars boolean DEFAULT TRUE NOT NULL; + +ALTER TABLE user_ + ADD COLUMN send_notifications_to_email boolean DEFAULT FALSE NOT NULL; -- Rebuild the user_view -drop view user_view; -create view user_view as -select id, -name, -avatar, -email, -fedi_name, -admin, -banned, -show_avatars, -send_notifications_to_email, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + email, + fedi_name, + admin, + banned, + show_avatars, + send_notifications_to_email, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + diff --git a/migrations/2020-01-11-012452_add_indexes/down.sql b/migrations/2020-01-11-012452_add_indexes/down.sql index ad674c50..b6e9b25b 100644 --- a/migrations/2020-01-11-012452_add_indexes/down.sql +++ b/migrations/2020-01-11-012452_add_indexes/down.sql @@ -1,16 +1,24 @@ -drop index idx_post_creator; -drop index idx_post_community; +DROP INDEX idx_post_creator; -drop index idx_post_like_post; -drop index idx_post_like_user; +DROP INDEX idx_post_community; -drop index idx_comment_creator; -drop index idx_comment_parent; -drop index idx_comment_post; +DROP INDEX idx_post_like_post; -drop index idx_comment_like_comment; -drop index idx_comment_like_user; -drop index idx_comment_like_post; +DROP INDEX idx_post_like_user; + +DROP INDEX idx_comment_creator; + +DROP INDEX idx_comment_parent; + +DROP INDEX idx_comment_post; + +DROP INDEX idx_comment_like_comment; + +DROP INDEX idx_comment_like_user; + +DROP INDEX idx_comment_like_post; + +DROP INDEX idx_community_creator; + +DROP INDEX idx_community_category; -drop index idx_community_creator; -drop index idx_community_category; diff --git a/migrations/2020-01-11-012452_add_indexes/up.sql b/migrations/2020-01-11-012452_add_indexes/up.sql index 911f0875..896e2add 100644 --- a/migrations/2020-01-11-012452_add_indexes/up.sql +++ b/migrations/2020-01-11-012452_add_indexes/up.sql @@ -1,17 +1,25 @@ -- Go through all the tables joins, optimize every view, CTE, etc. -create index idx_post_creator on post (creator_id); -create index idx_post_community on post (community_id); +CREATE INDEX idx_post_creator ON post (creator_id); -create index idx_post_like_post on post_like (post_id); -create index idx_post_like_user on post_like (user_id); +CREATE INDEX idx_post_community ON post (community_id); -create index idx_comment_creator on comment (creator_id); -create index idx_comment_parent on comment (parent_id); -create index idx_comment_post on comment (post_id); +CREATE INDEX idx_post_like_post ON post_like (post_id); -create index idx_comment_like_comment on comment_like (comment_id); -create index idx_comment_like_user on comment_like (user_id); -create index idx_comment_like_post on comment_like (post_id); +CREATE INDEX idx_post_like_user ON post_like (user_id); + +CREATE INDEX idx_comment_creator ON comment (creator_id); + +CREATE INDEX idx_comment_parent ON comment (parent_id); + +CREATE INDEX idx_comment_post ON comment (post_id); + +CREATE INDEX idx_comment_like_comment ON comment_like (comment_id); + +CREATE INDEX idx_comment_like_user ON comment_like (user_id); + +CREATE INDEX idx_comment_like_post ON comment_like (post_id); + +CREATE INDEX idx_community_creator ON community (creator_id); + +CREATE INDEX idx_community_category ON community (category_id); -create index idx_community_creator on community (creator_id); -create index idx_community_category on community (category_id); diff --git a/migrations/2020-01-13-025151_create_materialized_views/down.sql b/migrations/2020-01-13-025151_create_materialized_views/down.sql index 39985ab5..778e483c 100644 --- a/migrations/2020-01-13-025151_create_materialized_views/down.sql +++ b/migrations/2020-01-13-025151_create_materialized_views/down.sql @@ -1,202 +1,457 @@ -- functions and triggers -drop trigger refresh_user on user_; -drop function refresh_user(); -drop trigger refresh_post on post; -drop function refresh_post(); -drop trigger refresh_post_like on post_like; -drop function refresh_post_like(); -drop trigger refresh_community on community; -drop function refresh_community(); -drop trigger refresh_community_follower on community_follower; -drop function refresh_community_follower(); -drop trigger refresh_community_user_ban on community_user_ban; -drop function refresh_community_user_ban(); -drop trigger refresh_comment on comment; -drop function refresh_comment(); -drop trigger refresh_comment_like on comment_like; -drop function refresh_comment_like(); +DROP TRIGGER refresh_user ON user_; + +DROP FUNCTION refresh_user (); + +DROP TRIGGER refresh_post ON post; + +DROP FUNCTION refresh_post (); + +DROP TRIGGER refresh_post_like ON post_like; + +DROP FUNCTION refresh_post_like (); + +DROP TRIGGER refresh_community ON community; + +DROP FUNCTION refresh_community (); + +DROP TRIGGER refresh_community_follower ON community_follower; + +DROP FUNCTION refresh_community_follower (); + +DROP TRIGGER refresh_community_user_ban ON community_user_ban; + +DROP FUNCTION refresh_community_user_ban (); + +DROP TRIGGER refresh_comment ON comment; + +DROP FUNCTION refresh_comment (); + +DROP TRIGGER refresh_comment_like ON comment_like; + +DROP FUNCTION refresh_comment_like (); -- post -- Recreate the view -drop view post_view; -create view post_view as -with all_post as -( - select - p.*, - (select u.banned from user_ u where p.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where p.creator_id = user_.id) as creator_name, - (select avatar from user_ where p.creator_id = user_.id) as creator_avatar, - (select name from community where p.community_id = community.id) as community_name, - (select removed from community c where p.community_id = c.id) as community_removed, - (select deleted from community c where p.community_id = c.id) as community_deleted, - (select nsfw from community c where p.community_id = c.id) as community_nsfw, - (select count(*) from comment where comment.post_id = p.id) as number_of_comments, - coalesce(sum(pl.score), 0) as score, - count (case when pl.score = 1 then 1 else null end) as upvotes, - count (case when pl.score = -1 then 1 else null end) as downvotes, - hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank - from post p - left join post_like pl on p.id = pl.post_id - group by p.id +DROP VIEW post_view; + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.id ) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +DROP VIEW post_mview; -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP VIEW post_aggregates_view; -- user -drop materialized view user_mview; -drop view user_view; -create view user_view as -select id, -name, -avatar, -email, -fedi_name, -admin, -banned, -show_avatars, -send_notifications_to_email, -published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP MATERIALIZED VIEW user_mview; + +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + id, + name, + avatar, + email, + fedi_name, + admin, + banned, + show_avatars, + send_notifications_to_email, + published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -- community -drop view community_mview; -drop materialized view community_aggregates_mview; -drop view community_view; -drop view community_aggregates_view; -create view community_view as -with all_community as -( - select *, - (select name from user_ u where c.creator_id = u.id) as creator_name, - (select avatar from user_ u where c.creator_id = u.id) as creator_avatar, - (select name from category ct where c.category_id = ct.id) as category_name, - (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, - (select count(*) from post p where p.community_id = c.id) as number_of_posts, - (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, - hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank - from community c -) +DROP VIEW community_mview; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +DROP MATERIALIZED VIEW community_aggregates_mview; -union all +DROP VIEW community_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +DROP VIEW community_aggregates_view; --- reply and comment view -drop view reply_view; -drop view user_mention_view; -drop view comment_view; -drop view comment_mview; -drop materialized view comment_aggregates_mview; -drop view comment_aggregates_view; -create view comment_view as -with all_comment as -( - select - c.*, - (select community_id from post p where p.id = c.post_id), - (select u.banned from user_ u where c.creator_id = u.id) as banned, - (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, - (select name from user_ where c.creator_id = user_.id) as creator_name, - (select avatar from user_ where c.creator_id = user_.id) as creator_avatar, - coalesce(sum(cl.score), 0) as score, - count (case when cl.score = 1 then 1 else null end) as upvotes, - count (case when cl.score = -1 then 1 else null end) as downvotes - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.id +CREATE VIEW community_view AS +with all_community AS ( + SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; + +-- reply and comment view +DROP VIEW reply_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW user_mention_view; -union all +DROP VIEW comment_view; -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +DROP VIEW comment_mview; + +DROP MATERIALIZED VIEW comment_aggregates_mview; + +DROP VIEW comment_aggregates_view; + +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.id +) + SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -218,6 +473,9 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; diff --git a/migrations/2020-01-13-025151_create_materialized_views/up.sql b/migrations/2020-01-13-025151_create_materialized_views/up.sql index e0f206d3..47fc5e0f 100644 --- a/migrations/2020-01-13-025151_create_materialized_views/up.sql +++ b/migrations/2020-01-13-025151_create_materialized_views/up.sql @@ -1,285 +1,565 @@ -- post -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank -from post p -left join post_like pl on p.id = pl.post_id -group by p.id; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -drop view post_view; -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id +GROUP BY + p.id; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +DROP VIEW post_view; + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- user_view -drop view user_view; -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.fedi_name, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; - -create materialized view user_mview as select * from user_view; - -create unique index idx_user_mview_id on user_mview (id); +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.fedi_name, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- community -create view community_aggregates_view as -select c.*, -(select name from user_ u where c.creator_id = u.id) as creator_name, -(select avatar from user_ u where c.creator_id = u.id) as creator_avatar, -(select name from category ct where c.category_id = ct.id) as category_name, -(select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, -(select count(*) from post p where p.community_id = c.id) as number_of_posts, -(select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, -hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank -from community c; - -create materialized view community_aggregates_mview as select * from community_aggregates_view; - -create unique index idx_community_aggregates_mview_id on community_aggregates_mview (id); - -drop view community_view; -create view community_view as -with all_community as -( - select - ca.* - from community_aggregates_view ca +CREATE VIEW community_aggregates_view AS +SELECT + c.*, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c; + +CREATE MATERIALIZED VIEW community_aggregates_mview AS +SELECT + * +FROM + community_aggregates_view; + +CREATE UNIQUE INDEX idx_community_aggregates_mview_id ON community_aggregates_mview (id); + +DROP VIEW community_view; + +CREATE VIEW community_view AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_view ca ) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - -create view community_mview as -with all_community as -( - select - ca.* - from community_aggregates_mview ca +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; + +CREATE VIEW community_mview AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_mview ca ) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; - -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; - -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); - -drop view reply_view; -drop view user_mention_view; -drop view comment_view; - -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; + +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; + +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); + +DROP VIEW reply_view; + +DROP VIEW user_mention_view; + +DROP VIEW comment_view; + +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca ) - -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select +SELECT ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select +SELECT ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; - -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -301,137 +581,150 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -- user -create or replace function refresh_user() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently user_mview; - refresh materialized view concurrently comment_aggregates_mview; -- cause of bans - refresh materialized view concurrently post_aggregates_mview; - return null; -end $$; - -create trigger refresh_user -after insert or update or delete or truncate -on user_ -for each statement -execute procedure refresh_user(); +CREATE OR REPLACE FUNCTION refresh_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY comment_aggregates_mview; + -- cause of bans + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_user + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON user_ + FOR EACH statement + EXECUTE PROCEDURE refresh_user (); -- post -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -create trigger refresh_post -after insert or update or delete or truncate -on post -for each statement -execute procedure refresh_post(); +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_post + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON post + FOR EACH statement + EXECUTE PROCEDURE refresh_post (); -- post_like -create or replace function refresh_post_like() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -create trigger refresh_post_like -after insert or update or delete or truncate -on post_like -for each statement -execute procedure refresh_post_like(); +CREATE OR REPLACE FUNCTION refresh_post_like () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_post_like + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON post_like + FOR EACH statement + EXECUTE PROCEDURE refresh_post_like (); -- community -create or replace function refresh_community() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently community_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -create trigger refresh_community -after insert or update or delete or truncate -on community -for each statement -execute procedure refresh_community(); +CREATE OR REPLACE FUNCTION refresh_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY community_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_community + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON community + FOR EACH statement + EXECUTE PROCEDURE refresh_community (); -- community_follower -create or replace function refresh_community_follower() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently community_aggregates_mview; - refresh materialized view concurrently post_aggregates_mview; - return null; -end $$; - -create trigger refresh_community_follower -after insert or update or delete or truncate -on community_follower -for each statement -execute procedure refresh_community_follower(); +CREATE OR REPLACE FUNCTION refresh_community_follower () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY community_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_community_follower + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON community_follower + FOR EACH statement + EXECUTE PROCEDURE refresh_community_follower (); -- community_user_ban -create or replace function refresh_community_user_ban() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently comment_aggregates_mview; - refresh materialized view concurrently post_aggregates_mview; - return null; -end $$; - -create trigger refresh_community_user_ban -after insert or update or delete or truncate -on community_user_ban -for each statement -execute procedure refresh_community_user_ban(); +CREATE OR REPLACE FUNCTION refresh_community_user_ban () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY comment_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_community_user_ban + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON community_user_ban + FOR EACH statement + EXECUTE PROCEDURE refresh_community_user_ban (); -- comment -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently comment_aggregates_mview; - refresh materialized view concurrently community_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -create trigger refresh_comment -after insert or update or delete or truncate -on comment -for each statement -execute procedure refresh_comment(); +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY comment_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY community_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_comment + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON comment + FOR EACH statement + EXECUTE PROCEDURE refresh_comment (); -- comment_like -create or replace function refresh_comment_like() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently comment_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -create trigger refresh_comment_like -after insert or update or delete or truncate -on comment_like -for each statement -execute procedure refresh_comment_like(); +CREATE OR REPLACE FUNCTION refresh_comment_like () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY comment_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_comment_like + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON comment_like + FOR EACH statement + EXECUTE PROCEDURE refresh_comment_like (); + diff --git a/migrations/2020-01-21-001001_create_private_message/down.sql b/migrations/2020-01-21-001001_create_private_message/down.sql index 0d951e3e..9b55f39e 100644 --- a/migrations/2020-01-21-001001_create_private_message/down.sql +++ b/migrations/2020-01-21-001001_create_private_message/down.sql @@ -1,34 +1,72 @@ -- Drop the triggers -drop trigger refresh_private_message on private_message; -drop function refresh_private_message(); +DROP TRIGGER refresh_private_message ON private_message; + +DROP FUNCTION refresh_private_message (); -- Drop the view and table -drop view private_message_view cascade; -drop table private_message; +DROP VIEW private_message_view CASCADE; + +DROP TABLE private_message; -- Rebuild the old views -drop view user_view cascade; -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.fedi_name, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; - -create materialized view user_mview as select * from user_view; - -create unique index idx_user_mview_id on user_mview (id); +DROP VIEW user_view CASCADE; + +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.fedi_name, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- Drop the columns -alter table user_ drop column matrix_user_id; +ALTER TABLE user_ + DROP COLUMN matrix_user_id; + diff --git a/migrations/2020-01-21-001001_create_private_message/up.sql b/migrations/2020-01-21-001001_create_private_message/up.sql index 48e16dd8..cb19eb42 100644 --- a/migrations/2020-01-21-001001_create_private_message/up.sql +++ b/migrations/2020-01-21-001001_create_private_message/up.sql @@ -1,76 +1,117 @@ -- Creating private message -create table private_message ( - id serial primary key, - creator_id int references user_ on update cascade on delete cascade not null, - recipient_id int references user_ on update cascade on delete cascade not null, - content text not null, - deleted boolean default false not null, - read boolean default false not null, - published timestamp not null default now(), - updated timestamp +CREATE TABLE private_message ( + id serial PRIMARY KEY, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + recipient_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + content text NOT NULL, + deleted boolean DEFAULT FALSE NOT NULL, + read boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); -- Create the view and materialized view which has the avatar and creator name -create view private_message_view as -select -pm.*, -u.name as creator_name, -u.avatar as creator_avatar, -u2.name as recipient_name, -u2.avatar as recipient_avatar -from private_message pm -inner join user_ u on u.id = pm.creator_id -inner join user_ u2 on u2.id = pm.recipient_id; +CREATE VIEW private_message_view AS +SELECT + pm.*, + u.name AS creator_name, + u.avatar AS creator_avatar, + u2.name AS recipient_name, + u2.avatar AS recipient_avatar +FROM + private_message pm + INNER JOIN user_ u ON u.id = pm.creator_id + INNER JOIN user_ u2 ON u2.id = pm.recipient_id; -create materialized view private_message_mview as select * from private_message_view; +CREATE MATERIALIZED VIEW private_message_mview AS +SELECT + * +FROM + private_message_view; -create unique index idx_private_message_mview_id on private_message_mview (id); +CREATE UNIQUE INDEX idx_private_message_mview_id ON private_message_mview (id); -- Create the triggers -create or replace function refresh_private_message() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently private_message_mview; - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_private_message () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY private_message_mview; + RETURN NULL; +END +$$; -create trigger refresh_private_message -after insert or update or delete or truncate -on private_message -for each statement -execute procedure refresh_private_message(); +CREATE TRIGGER refresh_private_message + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON private_message + FOR EACH statement + EXECUTE PROCEDURE refresh_private_message (); -- Update user to include matrix id -alter table user_ add column matrix_user_id text unique; +ALTER TABLE user_ + ADD COLUMN matrix_user_id text UNIQUE; -drop view user_view cascade; -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.fedi_name, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +DROP VIEW user_view CASCADE; -create materialized view user_mview as select * from user_view; +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.fedi_name, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -create unique index idx_user_mview_id on user_mview (id); +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- This is what a group pm table would look like -- Not going to do it now because of the complications --- +-- -- create table private_message ( -- id serial primary key, -- creator_id int references user_ on update cascade on delete cascade not null, @@ -79,7 +120,7 @@ create unique index idx_user_mview_id on user_mview (id); -- published timestamp not null default now(), -- updated timestamp -- ); --- +-- -- create table private_message_recipient ( -- id serial primary key, -- private_message_id int references private_message on update cascade on delete cascade not null, diff --git a/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql b/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql index 06ec5971..ae32a42e 100644 --- a/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql +++ b/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql @@ -1,25 +1,37 @@ -- Drop the materialized / built views -drop view reply_view; -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +DROP VIEW reply_view; + +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_view cv, + closereply +WHERE + closereply.id = cv.id; + diff --git a/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql b/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql index ebbb1dff..f6a291d2 100644 --- a/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql +++ b/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql @@ -1,27 +1,38 @@ -- https://github.com/dessalines/lemmy/issues/197 -drop view reply_view; +DROP VIEW reply_view; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; + diff --git a/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql b/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql index d93ebc2e..99d0856c 100644 --- a/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql +++ b/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql @@ -1 +1,2 @@ -drop view user_mention_mview; +DROP VIEW user_mention_mview; + diff --git a/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql b/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql index b0ae4e9d..0130f326 100644 --- a/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql +++ b/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql @@ -1,14 +1,13 @@ -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -26,20 +25,27 @@ select ac.score, ac.upvotes, ac.downvotes, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -57,11 +63,11 @@ select ac.score, ac.upvotes, ac.downvotes, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-02-02-004806_add_case_insensitive_usernames/down.sql b/migrations/2020-02-02-004806_add_case_insensitive_usernames/down.sql index 0c6f112f..d7452a00 100644 --- a/migrations/2020-02-02-004806_add_case_insensitive_usernames/down.sql +++ b/migrations/2020-02-02-004806_add_case_insensitive_usernames/down.sql @@ -1,2 +1,4 @@ -drop index idx_user_name_lower; -drop index idx_user_email_lower; +DROP INDEX idx_user_name_lower; + +DROP INDEX idx_user_email_lower; + diff --git a/migrations/2020-02-02-004806_add_case_insensitive_usernames/up.sql b/migrations/2020-02-02-004806_add_case_insensitive_usernames/up.sql index 07f854b1..5cf7e049 100644 --- a/migrations/2020-02-02-004806_add_case_insensitive_usernames/up.sql +++ b/migrations/2020-02-02-004806_add_case_insensitive_usernames/up.sql @@ -1,5 +1,4 @@ -- Add case insensitive username and email uniqueness - -- An example of showing the dupes: -- select -- max(id) as id, @@ -8,22 +7,28 @@ -- from user_ -- group by lower(name) -- having count(*) > 1; - -- Delete username dupes, keeping the first one -delete -from user_ -where id not in ( - select min(id) - from user_ - group by lower(name), lower(fedi_name) -); +DELETE FROM user_ +WHERE id NOT IN ( + SELECT + min(id) + FROM + user_ + GROUP BY + lower(name), + lower(fedi_name)); --- The user index -create unique index idx_user_name_lower on user_ (lower(name)); +-- The user index +CREATE UNIQUE INDEX idx_user_name_lower ON user_ (lower(name)); -- Email lower -create unique index idx_user_email_lower on user_ (lower(email)); +CREATE UNIQUE INDEX idx_user_email_lower ON user_ (lower(email)); -- Set empty emails properly to null -update user_ set email = null where email = ''; +UPDATE + user_ +SET + email = NULL +WHERE + email = ''; diff --git a/migrations/2020-02-06-165953_change_post_title_length/down.sql b/migrations/2020-02-06-165953_change_post_title_length/down.sql index 2bc765f8..19a5c37e 100644 --- a/migrations/2020-02-06-165953_change_post_title_length/down.sql +++ b/migrations/2020-02-06-165953_change_post_title_length/down.sql @@ -1,132 +1,409 @@ -- Drop the dependent views -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; -drop view mod_remove_post_view; -drop view mod_sticky_post_view; -drop view mod_lock_post_view; -drop view mod_remove_comment_view; +DROP VIEW post_view; -alter table post alter column name type varchar(100); +DROP VIEW post_mview; + +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP VIEW post_aggregates_view; + +DROP VIEW mod_remove_post_view; + +DROP VIEW mod_sticky_post_view; + +DROP VIEW mod_lock_post_view; + +DROP VIEW mod_remove_comment_view; + +ALTER TABLE post + ALTER COLUMN name TYPE varchar(100); -- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank -from post p -left join post_like pl on p.id = pl.post_id -group by p.id; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id +GROUP BY + p.id; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- The mod views +CREATE VIEW mod_remove_post_view AS +SELECT + mrp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mrp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_remove_post mrp; + +CREATE VIEW mod_lock_post_view AS +SELECT + mlp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mlp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mlp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_lock_post mlp; + +CREATE VIEW mod_remove_comment_view AS +SELECT + mrc.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrc.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + c.id + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_user_id, + ( + SELECT + name + FROM + user_ u, + comment c + WHERE + mrc.comment_id = c.id + AND u.id = c.creator_id) AS comment_user_name, + ( + SELECT + content + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_content, + ( + SELECT + p.id + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_id, + ( + SELECT + p.name + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_name, + ( + SELECT + co.id + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_id, + ( + SELECT + co.name + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_name +FROM + mod_remove_comment mrc; + +CREATE VIEW mod_sticky_post_view AS +SELECT + msp.*, + ( + SELECT + name + FROM + user_ u + WHERE + msp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + msp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_sticky_post msp; -create view mod_remove_post_view as -select mrp.*, -(select name from user_ u where mrp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mrp.post_id = p.id) as post_name, -(select c.id from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_name -from mod_remove_post mrp; - -create view mod_lock_post_view as -select mlp.*, -(select name from user_ u where mlp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mlp.post_id = p.id) as post_name, -(select c.id from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_name -from mod_lock_post mlp; - -create view mod_remove_comment_view as -select mrc.*, -(select name from user_ u where mrc.mod_user_id = u.id) as mod_user_name, -(select c.id from comment c where mrc.comment_id = c.id) as comment_user_id, -(select name from user_ u, comment c where mrc.comment_id = c.id and u.id = c.creator_id) as comment_user_name, -(select content from comment c where mrc.comment_id = c.id) as comment_content, -(select p.id from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_id, -(select p.name from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_name, -(select co.id from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_id, -(select co.name from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_name -from mod_remove_comment mrc; - -create view mod_sticky_post_view as -select msp.*, -(select name from user_ u where msp.mod_user_id = u.id) as mod_user_name, -(select name from post p where msp.post_id = p.id) as post_name, -(select c.id from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_name -from mod_sticky_post msp; diff --git a/migrations/2020-02-06-165953_change_post_title_length/up.sql b/migrations/2020-02-06-165953_change_post_title_length/up.sql index 006a7d04..b0ed7254 100644 --- a/migrations/2020-02-06-165953_change_post_title_length/up.sql +++ b/migrations/2020-02-06-165953_change_post_title_length/up.sql @@ -1,133 +1,410 @@ -- Drop the dependent views -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; -drop view mod_remove_post_view; -drop view mod_sticky_post_view; -drop view mod_lock_post_view; -drop view mod_remove_comment_view; +DROP VIEW post_view; + +DROP VIEW post_mview; + +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP VIEW post_aggregates_view; + +DROP VIEW mod_remove_post_view; + +DROP VIEW mod_sticky_post_view; + +DROP VIEW mod_lock_post_view; + +DROP VIEW mod_remove_comment_view; -- Add the extra post limit -alter table post alter column name type varchar(200); +ALTER TABLE post + ALTER COLUMN name TYPE varchar(200); -- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank -from post p -left join post_like pl on p.id = pl.post_id -group by p.id; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id +GROUP BY + p.id; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- The mod views +CREATE VIEW mod_remove_post_view AS +SELECT + mrp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mrp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mrp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_remove_post mrp; + +CREATE VIEW mod_lock_post_view AS +SELECT + mlp.*, + ( + SELECT + name + FROM + user_ u + WHERE + mlp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + mlp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + mlp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_lock_post mlp; + +CREATE VIEW mod_remove_comment_view AS +SELECT + mrc.*, + ( + SELECT + name + FROM + user_ u + WHERE + mrc.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + c.id + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_user_id, + ( + SELECT + name + FROM + user_ u, + comment c + WHERE + mrc.comment_id = c.id + AND u.id = c.creator_id) AS comment_user_name, + ( + SELECT + content + FROM + comment c + WHERE + mrc.comment_id = c.id) AS comment_content, + ( + SELECT + p.id + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_id, + ( + SELECT + p.name + FROM + post p, + comment c + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id) AS post_name, + ( + SELECT + co.id + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_id, + ( + SELECT + co.name + FROM + comment c, + post p, + community co + WHERE + mrc.comment_id = c.id + AND c.post_id = p.id + AND p.community_id = co.id) AS community_name +FROM + mod_remove_comment mrc; + +CREATE VIEW mod_sticky_post_view AS +SELECT + msp.*, + ( + SELECT + name + FROM + user_ u + WHERE + msp.mod_user_id = u.id) AS mod_user_name, + ( + SELECT + name + FROM + post p + WHERE + msp.post_id = p.id) AS post_name, + ( + SELECT + c.id + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_id, + ( + SELECT + c.name + FROM + post p, + community c + WHERE + msp.post_id = p.id + AND p.community_id = c.id) AS community_name +FROM + mod_sticky_post msp; -create view mod_remove_post_view as -select mrp.*, -(select name from user_ u where mrp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mrp.post_id = p.id) as post_name, -(select c.id from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mrp.post_id = p.id and p.community_id = c.id) as community_name -from mod_remove_post mrp; - -create view mod_lock_post_view as -select mlp.*, -(select name from user_ u where mlp.mod_user_id = u.id) as mod_user_name, -(select name from post p where mlp.post_id = p.id) as post_name, -(select c.id from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where mlp.post_id = p.id and p.community_id = c.id) as community_name -from mod_lock_post mlp; - -create view mod_remove_comment_view as -select mrc.*, -(select name from user_ u where mrc.mod_user_id = u.id) as mod_user_name, -(select c.id from comment c where mrc.comment_id = c.id) as comment_user_id, -(select name from user_ u, comment c where mrc.comment_id = c.id and u.id = c.creator_id) as comment_user_name, -(select content from comment c where mrc.comment_id = c.id) as comment_content, -(select p.id from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_id, -(select p.name from post p, comment c where mrc.comment_id = c.id and c.post_id = p.id) as post_name, -(select co.id from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_id, -(select co.name from comment c, post p, community co where mrc.comment_id = c.id and c.post_id = p.id and p.community_id = co.id) as community_name -from mod_remove_comment mrc; - -create view mod_sticky_post_view as -select msp.*, -(select name from user_ u where msp.mod_user_id = u.id) as mod_user_name, -(select name from post p where msp.post_id = p.id) as post_name, -(select c.id from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_id, -(select c.name from post p, community c where msp.post_id = p.id and p.community_id = c.id) as community_name -from mod_sticky_post msp; diff --git a/migrations/2020-02-07-210055_add_comment_subscribed/down.sql b/migrations/2020-02-07-210055_add_comment_subscribed/down.sql index b6120d15..56edcaea 100644 --- a/migrations/2020-02-07-210055_add_comment_subscribed/down.sql +++ b/migrations/2020-02-07-210055_add_comment_subscribed/down.sql @@ -1,117 +1,191 @@ +DROP VIEW reply_view; -drop view reply_view; -drop view user_mention_view; -drop view user_mention_mview; -drop view comment_view; -drop view comment_mview; -drop materialized view comment_aggregates_mview; -drop view comment_aggregates_view; +DROP VIEW user_mention_view; --- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; - -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; +DROP VIEW user_mention_mview; -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); - -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca -) +DROP VIEW comment_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW comment_mview; -union all +DROP MATERIALIZED VIEW comment_aggregates_mview; -select - ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; +DROP VIEW comment_aggregates_view; -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca -) +-- reply and comment view +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; -union all +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); -select +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca +) +SELECT ac.*, - null as user_id, - null as my_vote, - null as saved -from all_comment ac -; + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca +) +SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved + FROM + all_comment ac; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -133,21 +207,22 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; - +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -165,20 +240,27 @@ select ac.score, ac.upvotes, ac.downvotes, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -196,11 +278,11 @@ select ac.score, ac.upvotes, ac.downvotes, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-02-07-210055_add_comment_subscribed/up.sql b/migrations/2020-02-07-210055_add_comment_subscribed/up.sql index 8836a571..bdff8c1d 100644 --- a/migrations/2020-02-07-210055_add_comment_subscribed/up.sql +++ b/migrations/2020-02-07-210055_add_comment_subscribed/up.sql @@ -1,125 +1,221 @@ - -- Adding community name, hot_rank, to comment_view, user_mention_view, and subscribed to comment_view - -- Rebuild the comment view -drop view reply_view; -drop view user_mention_view; -drop view user_mention_mview; -drop view comment_view; -drop view comment_mview; -drop materialized view comment_aggregates_mview; -drop view comment_aggregates_view; +DROP VIEW reply_view; --- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select co.name from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_name, -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(cl.score) , 0), c.published) as hot_rank -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; +DROP VIEW user_mention_view; -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; +DROP VIEW user_mention_mview; -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); +DROP VIEW comment_view; -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca -) +DROP VIEW comment_mview; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP MATERIALIZED VIEW comment_aggregates_mview; -union all +DROP VIEW comment_aggregates_view; -select - ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; +-- reply and comment view +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + co.name + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_name, + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(cl.score), 0), c.published) AS hot_rank +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca -) +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); -union all +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca +) +SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; -select +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca +) +SELECT ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -143,21 +239,22 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; - +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -177,20 +274,27 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -210,11 +314,11 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-02-08-145624_add_post_newest_activity_time/down.sql b/migrations/2020-02-08-145624_add_post_newest_activity_time/down.sql index 8b912fa3..3bf7bfc5 100644 --- a/migrations/2020-02-08-145624_add_post_newest_activity_time/down.sql +++ b/migrations/2020-02-08-145624_add_post_newest_activity_time/down.sql @@ -1,88 +1,206 @@ -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP VIEW post_view; --- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank -from post p -left join post_like pl on p.id = pl.post_id -group by p.id; +DROP VIEW post_mview; -create materialized view post_aggregates_mview as select * from post_aggregates_view; +DROP MATERIALIZED VIEW post_aggregates_mview; -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); +DROP VIEW post_aggregates_view; -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +-- regen post view +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), p.published) AS hot_rank +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id +GROUP BY + p.id; -union all +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; diff --git a/migrations/2020-02-08-145624_add_post_newest_activity_time/up.sql b/migrations/2020-02-08-145624_add_post_newest_activity_time/up.sql index e1541277..a0240657 100644 --- a/migrations/2020-02-08-145624_add_post_newest_activity_time/up.sql +++ b/migrations/2020-02-08-145624_add_post_newest_activity_time/up.sql @@ -1,106 +1,227 @@ -- Adds a newest_activity_time for the post_views, in order to sort by newest comment -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP VIEW post_view; --- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; +DROP VIEW post_mview; -create materialized view post_aggregates_mview as select * from post_aggregates_view; +DROP MATERIALIZED VIEW post_aggregates_mview; -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); +DROP VIEW post_aggregates_view; -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +-- regen post view +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; -union all +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; diff --git a/migrations/2020-03-06-202329_add_post_iframely_data/down.sql b/migrations/2020-03-06-202329_add_post_iframely_data/down.sql index 71dcc6ba..08a99353 100644 --- a/migrations/2020-03-06-202329_add_post_iframely_data/down.sql +++ b/migrations/2020-03-06-202329_add_post_iframely_data/down.sql @@ -1,112 +1,240 @@ -- Adds a newest_activity_time for the post_views, in order to sort by newest comment -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP VIEW post_view; + +DROP VIEW post_mview; + +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP VIEW post_aggregates_view; -- Drop the columns -alter table post drop column embed_title; -alter table post drop column embed_description; -alter table post drop column embed_html; -alter table post drop column thumbnail_url; +ALTER TABLE post + DROP COLUMN embed_title; --- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; +ALTER TABLE post + DROP COLUMN embed_description; -create materialized view post_aggregates_mview as select * from post_aggregates_view; +ALTER TABLE post + DROP COLUMN embed_html; -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); +ALTER TABLE post + DROP COLUMN thumbnail_url; -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +-- regen post view +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; -union all +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; diff --git a/migrations/2020-03-06-202329_add_post_iframely_data/up.sql b/migrations/2020-03-06-202329_add_post_iframely_data/up.sql index d431bb7f..c0d372db 100644 --- a/migrations/2020-03-06-202329_add_post_iframely_data/up.sql +++ b/migrations/2020-03-06-202329_add_post_iframely_data/up.sql @@ -1,115 +1,241 @@ -- Add the columns -alter table post add column embed_title text; -alter table post add column embed_description text; -alter table post add column embed_html text; -alter table post add column thumbnail_url text; +ALTER TABLE post + ADD COLUMN embed_title text; --- Regenerate the views +ALTER TABLE post + ADD COLUMN embed_description text; --- Adds a newest_activity_time for the post_views, in order to sort by newest comment -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +ALTER TABLE post + ADD COLUMN embed_html text; --- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; +ALTER TABLE post + ADD COLUMN thumbnail_url text; -create materialized view post_aggregates_mview as select * from post_aggregates_view; +-- Regenerate the views +-- Adds a newest_activity_time for the post_views, in order to sort by newest comment +DROP VIEW post_view; -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); +DROP VIEW post_mview; -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +DROP MATERIALIZED VIEW post_aggregates_mview; -union all +DROP VIEW post_aggregates_view; -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +-- regen post view +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; -union all +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; diff --git a/migrations/2020-03-26-192410_add_activitypub_tables/down.sql b/migrations/2020-03-26-192410_add_activitypub_tables/down.sql index b1710623..27963d85 100644 --- a/migrations/2020-03-26-192410_add_activitypub_tables/down.sql +++ b/migrations/2020-03-26-192410_add_activitypub_tables/down.sql @@ -1,16 +1,17 @@ -drop table activity; +DROP TABLE activity; -alter table user_ -drop column actor_id, -drop column private_key, -drop column public_key, -drop column bio, -drop column local, -drop column last_refreshed_at; +ALTER TABLE user_ + DROP COLUMN actor_id, + DROP COLUMN private_key, + DROP COLUMN public_key, + DROP COLUMN bio, + DROP COLUMN local, + DROP COLUMN last_refreshed_at; + +ALTER TABLE community + DROP COLUMN actor_id, + DROP COLUMN private_key, + DROP COLUMN public_key, + DROP COLUMN local, + DROP COLUMN last_refreshed_at; -alter table community -drop column actor_id, -drop column private_key, -drop column public_key, -drop column local, -drop column last_refreshed_at; diff --git a/migrations/2020-03-26-192410_add_activitypub_tables/up.sql b/migrations/2020-03-26-192410_add_activitypub_tables/up.sql index 06db580e..1359fa49 100644 --- a/migrations/2020-03-26-192410_add_activitypub_tables/up.sql +++ b/migrations/2020-03-26-192410_add_activitypub_tables/up.sql @@ -1,36 +1,35 @@ -- The Activitypub activity table -- All user actions must create a row here. -create table activity ( - id serial primary key, - user_id int references user_ on update cascade on delete cascade not null, -- Ensures that the user is set up here. - data jsonb not null, - local boolean not null default true, - published timestamp not null default now(), - updated timestamp +CREATE TABLE activity ( + id serial PRIMARY KEY, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- Ensures that the user is set up here. + data jsonb NOT NULL, + local boolean NOT NULL DEFAULT TRUE, + published timestamp NOT NULL DEFAULT now(), + updated timestamp ); -- Making sure that id is unique -create unique index idx_activity_unique_apid on activity ((data ->> 'id'::text)); +CREATE UNIQUE INDEX idx_activity_unique_apid ON activity ((data ->> 'id'::text)); -- Add federation columns to the two actor tables -alter table user_ +ALTER TABLE user_ -- TODO uniqueness constraints should be added on these 3 columns later -add column actor_id character varying(255) not null default 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local -add column bio text, -- not on community, already has description -add column local boolean not null default true, -add column private_key text, -- These need to be generated from code -add column public_key text, -add column last_refreshed_at timestamp not null default now() -- Used to re-fetch federated actor periodically + ADD COLUMN actor_id character varying(255) NOT NULL DEFAULT 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local + ADD COLUMN bio text, -- not on community, already has description + ADD COLUMN local boolean NOT NULL DEFAULT TRUE, + ADD COLUMN private_key text, -- These need to be generated from code + ADD COLUMN public_key text, + ADD COLUMN last_refreshed_at timestamp NOT NULL DEFAULT now() -- Used to re-fetch federated actor periodically ; -- Community -alter table community -add column actor_id character varying(255) not null default 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local -add column local boolean not null default true, -add column private_key text, -- These need to be generated from code -add column public_key text, -add column last_refreshed_at timestamp not null default now() -- Used to re-fetch federated actor periodically +ALTER TABLE community + ADD COLUMN actor_id character varying(255) NOT NULL DEFAULT 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local + ADD COLUMN local boolean NOT NULL DEFAULT TRUE, + ADD COLUMN private_key text, -- These need to be generated from code + ADD COLUMN public_key text, + ADD COLUMN last_refreshed_at timestamp NOT NULL DEFAULT now() -- Used to re-fetch federated actor periodically ; -- Don't worry about rebuilding the views right now. - diff --git a/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/down.sql b/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/down.sql index 50c95bb2..6df4cb9d 100644 --- a/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/down.sql +++ b/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/down.sql @@ -1,7 +1,8 @@ -alter table post -drop column ap_id, -drop column local; +ALTER TABLE post + DROP COLUMN ap_id, + DROP COLUMN local; + +ALTER TABLE comment + DROP COLUMN ap_id, + DROP COLUMN local; -alter table comment -drop column ap_id, -drop column local; diff --git a/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/up.sql b/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/up.sql index 6c930cd8..ab72ac21 100644 --- a/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/up.sql +++ b/migrations/2020-04-03-194936_add_activitypub_for_posts_and_comments/up.sql @@ -1,14 +1,11 @@ -- Add federation columns to post, comment - -alter table post +ALTER TABLE post -- TODO uniqueness constraints should be added on these 3 columns later -add column ap_id character varying(255) not null default 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local -add column local boolean not null default true -; + ADD COLUMN ap_id character varying(255) NOT NULL DEFAULT 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local + ADD COLUMN local boolean NOT NULL DEFAULT TRUE; -alter table comment +ALTER TABLE comment -- TODO uniqueness constraints should be added on these 3 columns later -add column ap_id character varying(255) not null default 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local -add column local boolean not null default true -; + ADD COLUMN ap_id character varying(255) NOT NULL DEFAULT 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local + ADD COLUMN local boolean NOT NULL DEFAULT TRUE; diff --git a/migrations/2020-04-07-135912_add_user_community_apub_constraints/down.sql b/migrations/2020-04-07-135912_add_user_community_apub_constraints/down.sql index 46fc953a..d2be7d33 100644 --- a/migrations/2020-04-07-135912_add_user_community_apub_constraints/down.sql +++ b/migrations/2020-04-07-135912_add_user_community_apub_constraints/down.sql @@ -1,36 +1,69 @@ -- User table -drop view user_view cascade; +DROP VIEW user_view CASCADE; -alter table user_ -add column fedi_name varchar(40) not null default 'http://fake.com'; +ALTER TABLE user_ + ADD COLUMN fedi_name varchar(40) NOT NULL DEFAULT 'http://fake.com'; -alter table user_ -add constraint user__name_fedi_name_key unique (name, fedi_name); +ALTER TABLE user_ + ADD CONSTRAINT user__name_fedi_name_key UNIQUE (name, fedi_name); -- Community -alter table community -add constraint community_name_key unique (name); +ALTER TABLE community + ADD CONSTRAINT community_name_key UNIQUE (name); +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.fedi_name, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.fedi_name, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; -create materialized view user_mview as select * from user_view; +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -create unique index idx_user_mview_id on user_mview (id); diff --git a/migrations/2020-04-07-135912_add_user_community_apub_constraints/up.sql b/migrations/2020-04-07-135912_add_user_community_apub_constraints/up.sql index de65191d..1d3ba63f 100644 --- a/migrations/2020-04-07-135912_add_user_community_apub_constraints/up.sql +++ b/migrations/2020-04-07-135912_add_user_community_apub_constraints/up.sql @@ -1,38 +1,70 @@ -- User table - -- Need to regenerate user_view, user_mview -drop view user_view cascade; +DROP VIEW user_view CASCADE; -- Remove the fedi_name constraint, drop that useless column -alter table user_ -drop constraint user__name_fedi_name_key; +ALTER TABLE user_ + DROP CONSTRAINT user__name_fedi_name_key; -alter table user_ -drop column fedi_name; +ALTER TABLE user_ + DROP COLUMN fedi_name; -- Community -alter table community -drop constraint community_name_key; +ALTER TABLE community + DROP CONSTRAINT community_name_key; -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; -create materialized view user_mview as select * from user_view; +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; -create unique index idx_user_mview_id on user_mview (id); +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); diff --git a/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql b/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql index ce2dde39..2e88d51f 100644 --- a/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql +++ b/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql @@ -1,345 +1,715 @@ -- user_view -drop view user_view cascade; - -create view user_view as -select -u.id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; - -create materialized view user_mview as select * from user_view; - -create unique index idx_user_mview_id on user_mview (id); +DROP VIEW user_view CASCADE; + +CREATE VIEW user_view AS +SELECT + u.id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- community_view -drop view community_aggregates_view cascade; -create view community_aggregates_view as -select c.*, -(select name from user_ u where c.creator_id = u.id) as creator_name, -(select avatar from user_ u where c.creator_id = u.id) as creator_avatar, -(select name from category ct where c.category_id = ct.id) as category_name, -(select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, -(select count(*) from post p where p.community_id = c.id) as number_of_posts, -(select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, -hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank -from community c; - -create materialized view community_aggregates_mview as select * from community_aggregates_view; - -create unique index idx_community_aggregates_mview_id on community_aggregates_mview (id); - -create view community_view as -with all_community as -( - select - ca.* - from community_aggregates_view ca +DROP VIEW community_aggregates_view CASCADE; + +CREATE VIEW community_aggregates_view AS +SELECT + c.*, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c; + +CREATE MATERIALIZED VIEW community_aggregates_mview AS +SELECT + * +FROM + community_aggregates_view; + +CREATE UNIQUE INDEX idx_community_aggregates_mview_id ON community_aggregates_mview (id); + +CREATE VIEW community_view AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_view ca ) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - -create view community_mview as -with all_community as -( - select - ca.* - from community_aggregates_mview ca +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; + +CREATE VIEW community_mview AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_mview ca ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +-- community views +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +CREATE VIEW community_moderator_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_moderator cm; + +CREATE VIEW community_follower_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cf.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cf.community_id = c.id) AS community_name +FROM + community_follower cf; + +CREATE VIEW community_user_ban_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_user_ban cm; -union all +-- post_view +DROP VIEW post_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +DROP VIEW post_mview; --- community views -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; - -create view community_moderator_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select name from community c where cm.community_id = c.id) as community_name -from community_moderator cm; - -create view community_follower_view as -select *, -(select name from user_ u where cf.user_id = u.id) as user_name, -(select avatar from user_ u where cf.user_id = u.id), -(select name from community c where cf.community_id = c.id) as community_name -from community_follower cf; - -create view community_user_ban_view as -select *, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select name from community c where cm.community_id = c.id) as community_name -from community_user_ban cm; +DROP MATERIALIZED VIEW post_aggregates_mview; --- post_view -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP VIEW post_aggregates_view; -- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- reply_view, comment_view, user_mention -drop view reply_view; -drop view user_mention_view; -drop view user_mention_mview; -drop view comment_view; -drop view comment_mview; -drop materialized view comment_aggregates_mview; -drop view comment_aggregates_view; +DROP VIEW reply_view; --- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select co.name from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_name, -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(cl.score) , 0), c.published) as hot_rank -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; - -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; - -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); - -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca -) +DROP VIEW user_mention_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW user_mention_mview; -union all +DROP VIEW comment_view; -select - ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; - -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca -) +DROP VIEW comment_mview; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP MATERIALIZED VIEW comment_aggregates_mview; -union all +DROP VIEW comment_aggregates_view; -select +-- reply and comment view +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + co.name + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_name, + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(cl.score), 0), c.published) AS hot_rank +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; + +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; + +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); + +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca +) +SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca +) +SELECT ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.post_id, c.parent_id, @@ -363,21 +733,22 @@ select c.my_vote, c.saved, um.recipient_id -from user_mention um, comment_view c -where um.comment_id = c.id; - - -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -397,20 +768,27 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.post_id, ac.parent_id, @@ -430,11 +808,11 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql b/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql index 02499fc2..534ecdc2 100644 --- a/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql +++ b/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql @@ -1,384 +1,890 @@ -- user_view -drop view user_view cascade; - -create view user_view as -select -u.id, -u.actor_id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.bio, -u.local, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; - -create materialized view user_mview as select * from user_view; - -create unique index idx_user_mview_id on user_mview (id); +DROP VIEW user_view CASCADE; + +CREATE VIEW user_view AS +SELECT + u.id, + u.actor_id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.bio, + u.local, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- community_view -drop view community_aggregates_view cascade; -create view community_aggregates_view as +DROP VIEW community_aggregates_view CASCADE; + +CREATE VIEW community_aggregates_view AS -- Now that there's public and private keys, you have to be explicit here -select c.id, -c.name, -c.title, -c.description, -c.category_id, -c.creator_id, -c.removed, -c.published, -c.updated, -c.deleted, -c.nsfw, -c.actor_id, -c.local, -c.last_refreshed_at, -(select actor_id from user_ u where c.creator_id = u.id) as creator_actor_id, -(select local from user_ u where c.creator_id = u.id) as creator_local, -(select name from user_ u where c.creator_id = u.id) as creator_name, -(select avatar from user_ u where c.creator_id = u.id) as creator_avatar, -(select name from category ct where c.category_id = ct.id) as category_name, -(select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, -(select count(*) from post p where p.community_id = c.id) as number_of_posts, -(select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, -hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank -from community c; - -create materialized view community_aggregates_mview as select * from community_aggregates_view; - -create unique index idx_community_aggregates_mview_id on community_aggregates_mview (id); - -create view community_view as -with all_community as -( - select - ca.* - from community_aggregates_view ca +SELECT + c.id, + c.name, + c.title, + c.description, + c.category_id, + c.creator_id, + c.removed, + c.published, + c.updated, + c.deleted, + c.nsfw, + c.actor_id, + c.local, + c.last_refreshed_at, + ( + SELECT + actor_id + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_local, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c; + +CREATE MATERIALIZED VIEW community_aggregates_mview AS +SELECT + * +FROM + community_aggregates_view; + +CREATE UNIQUE INDEX idx_community_aggregates_mview_id ON community_aggregates_mview (id); + +CREATE VIEW community_view AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_view ca ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - -create view community_mview as -with all_community as -( - select - ca.* - from community_aggregates_mview ca +CREATE VIEW community_mview AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_mview ca ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac +-- community views +DROP VIEW community_moderator_view; -union all +DROP VIEW community_follower_view; -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; +DROP VIEW community_user_ban_view; --- community views -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; - -create view community_moderator_view as -select *, -(select actor_id from user_ u where cm.user_id = u.id) as user_actor_id, -(select local from user_ u where cm.user_id = u.id) as user_local, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select actor_id from community c where cm.community_id = c.id) as community_actor_id, -(select local from community c where cm.community_id = c.id) as community_local, -(select name from community c where cm.community_id = c.id) as community_name -from community_moderator cm; - -create view community_follower_view as -select *, -(select actor_id from user_ u where cf.user_id = u.id) as user_actor_id, -(select local from user_ u where cf.user_id = u.id) as user_local, -(select name from user_ u where cf.user_id = u.id) as user_name, -(select avatar from user_ u where cf.user_id = u.id), -(select actor_id from community c where cf.community_id = c.id) as community_actor_id, -(select local from community c where cf.community_id = c.id) as community_local, -(select name from community c where cf.community_id = c.id) as community_name -from community_follower cf; - -create view community_user_ban_view as -select *, -(select actor_id from user_ u where cm.user_id = u.id) as user_actor_id, -(select local from user_ u where cm.user_id = u.id) as user_local, -(select name from user_ u where cm.user_id = u.id) as user_name, -(select avatar from user_ u where cm.user_id = u.id), -(select actor_id from community c where cm.community_id = c.id) as community_actor_id, -(select local from community c where cm.community_id = c.id) as community_local, -(select name from community c where cm.community_id = c.id) as community_name -from community_user_ban cm; +CREATE VIEW community_moderator_view AS +SELECT + *, + ( + SELECT + actor_id + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_local, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + actor_id + FROM + community c + WHERE + cm.community_id = c.id) AS community_actor_id, + ( + SELECT + local + FROM + community c + WHERE + cm.community_id = c.id) AS community_local, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_moderator cm; + +CREATE VIEW community_follower_view AS +SELECT + *, + ( + SELECT + actor_id + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_local, + ( + SELECT + name + FROM + user_ u + WHERE + cf.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cf.user_id = u.id), ( + SELECT + actor_id + FROM + community c + WHERE + cf.community_id = c.id) AS community_actor_id, + ( + SELECT + local + FROM + community c + WHERE + cf.community_id = c.id) AS community_local, + ( + SELECT + name + FROM + community c + WHERE + cf.community_id = c.id) AS community_name +FROM + community_follower cf; + +CREATE VIEW community_user_ban_view AS +SELECT + *, + ( + SELECT + actor_id + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_local, + ( + SELECT + name + FROM + user_ u + WHERE + cm.user_id = u.id) AS user_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + cm.user_id = u.id), ( + SELECT + actor_id + FROM + community c + WHERE + cm.community_id = c.id) AS community_actor_id, + ( + SELECT + local + FROM + community c + WHERE + cm.community_id = c.id) AS community_local, + ( + SELECT + name + FROM + community c + WHERE + cm.community_id = c.id) AS community_name +FROM + community_user_ban cm; -- post_view -drop view post_view; -drop view post_mview; -drop materialized view post_aggregates_mview; -drop view post_aggregates_view; +DROP VIEW post_view; + +DROP VIEW post_mview; + +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP VIEW post_aggregates_view; -- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select actor_id from user_ where p.creator_id = user_.id) as creator_actor_id, -(select local from user_ where p.creator_id = user_.id) as creator_local, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select actor_id from community where p.community_id = community.id) as community_actor_id, -(select local from community where p.community_id = community.id) as community_local, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa -) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + actor_id + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_local, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + actor_id + FROM + community + WHERE + p.community_id = community.id) AS community_actor_id, + ( + SELECT + local + FROM + community + WHERE + p.community_id = community.id) AS community_local, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa +) +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; -- reply_view, comment_view, user_mention -drop view reply_view; -drop view user_mention_view; -drop view user_mention_mview; -drop view comment_view; -drop view comment_mview; -drop materialized view comment_aggregates_mview; -drop view comment_aggregates_view; +DROP VIEW reply_view; --- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select co.actor_id from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_actor_id, -(select co.local from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_local, -(select co.name from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_name, -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select actor_id from user_ where c.creator_id = user_.id) as creator_actor_id, -(select local from user_ where c.creator_id = user_.id) as creator_local, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(cl.score) , 0), c.published) as hot_rank -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; - -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; - -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); - -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca -) +DROP VIEW user_mention_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW user_mention_mview; -union all +DROP VIEW comment_view; -select - ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; - -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca -) +DROP VIEW comment_mview; + +DROP MATERIALIZED VIEW comment_aggregates_mview; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW comment_aggregates_view; -union all +-- reply and comment view +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + co.actor_id + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_actor_id, + ( + SELECT + co.local + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_local, + ( + SELECT + co.name + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_name, + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + actor_id + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_local, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(cl.score), 0), c.published) AS hot_rank +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; -select +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; + +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); + +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca +) +SELECT + ac.*, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca +) +SELECT ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -406,23 +912,36 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; - - -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca -) + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -select +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca +) +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -446,22 +965,41 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -485,13 +1023,25 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-04-21-123957_remove_unique_user_constraints/down.sql b/migrations/2020-04-21-123957_remove_unique_user_constraints/down.sql index a172581a..c8128941 100644 --- a/migrations/2020-04-21-123957_remove_unique_user_constraints/down.sql +++ b/migrations/2020-04-21-123957_remove_unique_user_constraints/down.sql @@ -1,4 +1,5 @@ -- The username index -drop index idx_user_name_lower_actor_id; -create unique index idx_user_name_lower on user_ (lower(name)); +DROP INDEX idx_user_name_lower_actor_id; + +CREATE UNIQUE INDEX idx_user_name_lower ON user_ (lower(name)); diff --git a/migrations/2020-04-21-123957_remove_unique_user_constraints/up.sql b/migrations/2020-04-21-123957_remove_unique_user_constraints/up.sql index 969eab0b..5843fa28 100644 --- a/migrations/2020-04-21-123957_remove_unique_user_constraints/up.sql +++ b/migrations/2020-04-21-123957_remove_unique_user_constraints/up.sql @@ -1,2 +1,4 @@ -drop index idx_user_name_lower; -create unique index idx_user_name_lower_actor_id on user_ (lower(name), lower(actor_id)); +DROP INDEX idx_user_name_lower; + +CREATE UNIQUE INDEX idx_user_name_lower_actor_id ON user_ (lower(name), lower(actor_id)); + diff --git a/migrations/2020-05-05-210233_add_activitypub_for_private_messages/down.sql b/migrations/2020-05-05-210233_add_activitypub_for_private_messages/down.sql index 15c92859..76c74f6e 100644 --- a/migrations/2020-05-05-210233_add_activitypub_for_private_messages/down.sql +++ b/migrations/2020-05-05-210233_add_activitypub_for_private_messages/down.sql @@ -1,21 +1,28 @@ -drop materialized view private_message_mview; -drop view private_message_view; +DROP MATERIALIZED VIEW private_message_mview; -alter table private_message -drop column ap_id, -drop column local; +DROP VIEW private_message_view; -create view private_message_view as -select -pm.*, -u.name as creator_name, -u.avatar as creator_avatar, -u2.name as recipient_name, -u2.avatar as recipient_avatar -from private_message pm -inner join user_ u on u.id = pm.creator_id -inner join user_ u2 on u2.id = pm.recipient_id; +ALTER TABLE private_message + DROP COLUMN ap_id, + DROP COLUMN local; -create materialized view private_message_mview as select * from private_message_view; +CREATE VIEW private_message_view AS +SELECT + pm.*, + u.name AS creator_name, + u.avatar AS creator_avatar, + u2.name AS recipient_name, + u2.avatar AS recipient_avatar +FROM + private_message pm + INNER JOIN user_ u ON u.id = pm.creator_id + INNER JOIN user_ u2 ON u2.id = pm.recipient_id; + +CREATE MATERIALIZED VIEW private_message_mview AS +SELECT + * +FROM + private_message_view; + +CREATE UNIQUE INDEX idx_private_message_mview_id ON private_message_mview (id); -create unique index idx_private_message_mview_id on private_message_mview (id); diff --git a/migrations/2020-05-05-210233_add_activitypub_for_private_messages/up.sql b/migrations/2020-05-05-210233_add_activitypub_for_private_messages/up.sql index 9f152ada..6935d33c 100644 --- a/migrations/2020-05-05-210233_add_activitypub_for_private_messages/up.sql +++ b/migrations/2020-05-05-210233_add_activitypub_for_private_messages/up.sql @@ -1,25 +1,32 @@ -alter table private_message -add column ap_id character varying(255) not null default 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local -add column local boolean not null default true -; +ALTER TABLE private_message + ADD COLUMN ap_id character varying(255) NOT NULL DEFAULT 'http://fake.com', -- This needs to be checked and updated in code, building from the site url if local + ADD COLUMN local boolean NOT NULL DEFAULT TRUE; -drop materialized view private_message_mview; -drop view private_message_view; -create view private_message_view as -select -pm.*, -u.name as creator_name, -u.avatar as creator_avatar, -u.actor_id as creator_actor_id, -u.local as creator_local, -u2.name as recipient_name, -u2.avatar as recipient_avatar, -u2.actor_id as recipient_actor_id, -u2.local as recipient_local -from private_message pm -inner join user_ u on u.id = pm.creator_id -inner join user_ u2 on u2.id = pm.recipient_id; +DROP MATERIALIZED VIEW private_message_mview; -create materialized view private_message_mview as select * from private_message_view; +DROP VIEW private_message_view; + +CREATE VIEW private_message_view AS +SELECT + pm.*, + u.name AS creator_name, + u.avatar AS creator_avatar, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u2.name AS recipient_name, + u2.avatar AS recipient_avatar, + u2.actor_id AS recipient_actor_id, + u2.local AS recipient_local +FROM + private_message pm + INNER JOIN user_ u ON u.id = pm.creator_id + INNER JOIN user_ u2 ON u2.id = pm.recipient_id; + +CREATE MATERIALIZED VIEW private_message_mview AS +SELECT + * +FROM + private_message_view; + +CREATE UNIQUE INDEX idx_private_message_mview_id ON private_message_mview (id); -create unique index idx_private_message_mview_id on private_message_mview (id); diff --git a/migrations/2020-06-30-135809_remove_mat_views/down.sql b/migrations/2020-06-30-135809_remove_mat_views/down.sql index 5f72b76d..ea82e57b 100644 --- a/migrations/2020-06-30-135809_remove_mat_views/down.sql +++ b/migrations/2020-06-30-135809_remove_mat_views/down.sql @@ -1,422 +1,811 @@ -- Dropping all the fast tables -drop table user_fast; -drop view post_fast_view; -drop table post_aggregates_fast; -drop view community_fast_view; -drop table community_aggregates_fast; -drop view reply_fast_view; -drop view user_mention_fast_view; -drop view comment_fast_view; -drop table comment_aggregates_fast; +DROP TABLE user_fast; --- Re-adding all the triggers, functions, and mviews +DROP VIEW post_fast_view; --- private message -create materialized view private_message_mview as select * from private_message_view; +DROP TABLE post_aggregates_fast; + +DROP VIEW community_fast_view; + +DROP TABLE community_aggregates_fast; + +DROP VIEW reply_fast_view; -create unique index idx_private_message_mview_id on private_message_mview (id); +DROP VIEW user_mention_fast_view; + +DROP VIEW comment_fast_view; + +DROP TABLE comment_aggregates_fast; + +-- Re-adding all the triggers, functions, and mviews +-- private message +CREATE MATERIALIZED VIEW private_message_mview AS +SELECT + * +FROM + private_message_view; +CREATE UNIQUE INDEX idx_private_message_mview_id ON private_message_mview (id); -- Create the triggers -create or replace function refresh_private_message() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently private_message_mview; - return null; -end $$; - -create trigger refresh_private_message -after insert or update or delete or truncate -on private_message -for each statement -execute procedure refresh_private_message(); - --- user -create or replace function refresh_user() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently user_mview; - refresh materialized view concurrently comment_aggregates_mview; -- cause of bans - refresh materialized view concurrently post_aggregates_mview; - return null; -end $$; - -drop trigger refresh_user on user_; -create trigger refresh_user -after insert or update or delete or truncate -on user_ -for each statement -execute procedure refresh_user(); -drop view user_view cascade; - -create view user_view as -select -u.id, -u.actor_id, -u.name, -u.avatar, -u.email, -u.matrix_user_id, -u.bio, -u.local, -u.admin, -u.banned, -u.show_avatars, -u.send_notifications_to_email, -u.published, -(select count(*) from post p where p.creator_id = u.id) as number_of_posts, -(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score, -(select count(*) from comment c where c.creator_id = u.id) as number_of_comments, -(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score -from user_ u; - -create materialized view user_mview as select * from user_view; - -create unique index idx_user_mview_id on user_mview (id); +CREATE OR REPLACE FUNCTION refresh_private_message () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY private_message_mview; + RETURN NULL; +END +$$; + +CREATE TRIGGER refresh_private_message + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON private_message + FOR EACH statement + EXECUTE PROCEDURE refresh_private_message (); + +-- user +CREATE OR REPLACE FUNCTION refresh_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY comment_aggregates_mview; + -- cause of bans + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + RETURN NULL; +END +$$; + +DROP TRIGGER refresh_user ON user_; + +CREATE TRIGGER refresh_user + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON user_ + FOR EACH statement + EXECUTE PROCEDURE refresh_user (); + +DROP VIEW user_view CASCADE; + +CREATE VIEW user_view AS +SELECT + u.id, + u.actor_id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.bio, + u.local, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + ( + SELECT + count(*) + FROM + post p + WHERE + p.creator_id = u.id) AS number_of_posts, + ( + SELECT + coalesce(sum(score), 0) + FROM + post p, + post_like pl + WHERE + u.id = p.creator_id + AND p.id = pl.post_id) AS post_score, + ( + SELECT + count(*) + FROM + comment c + WHERE + c.creator_id = u.id) AS number_of_comments, + ( + SELECT + coalesce(sum(score), 0) + FROM + comment c, + comment_like cl + WHERE + u.id = c.creator_id + AND c.id = cl.comment_id) AS comment_score +FROM + user_ u; + +CREATE MATERIALIZED VIEW user_mview AS +SELECT + * +FROM + user_view; + +CREATE UNIQUE INDEX idx_user_mview_id ON user_mview (id); -- community -drop trigger refresh_community on community; -create trigger refresh_community -after insert or update or delete or truncate -on community -for each statement -execute procedure refresh_community(); - -create or replace function refresh_community() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently community_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - -drop view community_aggregates_view cascade; -create view community_aggregates_view as +DROP TRIGGER refresh_community ON community; + +CREATE TRIGGER refresh_community + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON community + FOR EACH statement + EXECUTE PROCEDURE refresh_community (); + +CREATE OR REPLACE FUNCTION refresh_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY community_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; + +DROP VIEW community_aggregates_view CASCADE; + +CREATE VIEW community_aggregates_view AS -- Now that there's public and private keys, you have to be explicit here -select c.id, -c.name, -c.title, -c.description, -c.category_id, -c.creator_id, -c.removed, -c.published, -c.updated, -c.deleted, -c.nsfw, -c.actor_id, -c.local, -c.last_refreshed_at, -(select actor_id from user_ u where c.creator_id = u.id) as creator_actor_id, -(select local from user_ u where c.creator_id = u.id) as creator_local, -(select name from user_ u where c.creator_id = u.id) as creator_name, -(select avatar from user_ u where c.creator_id = u.id) as creator_avatar, -(select name from category ct where c.category_id = ct.id) as category_name, -(select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, -(select count(*) from post p where p.community_id = c.id) as number_of_posts, -(select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, -hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank -from community c; - -create materialized view community_aggregates_mview as select * from community_aggregates_view; - -create unique index idx_community_aggregates_mview_id on community_aggregates_mview (id); - -create view community_view as -with all_community as -( - select - ca.* - from community_aggregates_view ca +SELECT + c.id, + c.name, + c.title, + c.description, + c.category_id, + c.creator_id, + c.removed, + c.published, + c.updated, + c.deleted, + c.nsfw, + c.actor_id, + c.local, + c.last_refreshed_at, + ( + SELECT + actor_id + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_local, + ( + SELECT + name + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + c.creator_id = u.id) AS creator_avatar, + ( + SELECT + name + FROM + category ct + WHERE + c.category_id = ct.id) AS category_name, + ( + SELECT + count(*) + FROM + community_follower cf + WHERE + cf.community_id = c.id) AS number_of_subscribers, + ( + SELECT + count(*) + FROM + post p + WHERE + p.community_id = c.id) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment co, + post p + WHERE + c.id = p.community_id + AND p.id = co.post_id) AS number_of_comments, + hot_rank (( + SELECT + count(*) + FROM community_follower cf + WHERE + cf.community_id = c.id), c.published) AS hot_rank +FROM + community c; + +CREATE MATERIALIZED VIEW community_aggregates_mview AS +SELECT + * +FROM + community_aggregates_view; + +CREATE UNIQUE INDEX idx_community_aggregates_mview_id ON community_aggregates_mview (id); + +CREATE VIEW community_view AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_view ca ) - -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; - -create view community_mview as -with all_community as -( - select - ca.* - from community_aggregates_mview ca +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; + +CREATE VIEW community_mview AS +with all_community AS ( + SELECT + ca.* + FROM + community_aggregates_mview ca ) +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN all_community ac +UNION ALL +SELECT + ac.*, + NULL AS user_id, + NULL AS subscribed +FROM + all_community ac; -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join all_community ac - -union all - -select -ac.*, -null as user_id, -null as subscribed -from all_community ac -; -- Post -drop view post_view; -drop view post_aggregates_view; +DROP VIEW post_view; + +DROP VIEW post_aggregates_view; -- regen post view -create view post_aggregates_view as -select -p.*, -(select u.banned from user_ u where p.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community, -(select actor_id from user_ where p.creator_id = user_.id) as creator_actor_id, -(select local from user_ where p.creator_id = user_.id) as creator_local, -(select name from user_ where p.creator_id = user_.id) as creator_name, -(select avatar from user_ where p.creator_id = user_.id) as creator_avatar, -(select actor_id from community where p.community_id = community.id) as community_actor_id, -(select local from community where p.community_id = community.id) as community_local, -(select name from community where p.community_id = community.id) as community_name, -(select removed from community c where p.community_id = c.id) as community_removed, -(select deleted from community c where p.community_id = c.id) as community_deleted, -(select nsfw from community c where p.community_id = c.id) as community_nsfw, -(select count(*) from comment where comment.post_id = p.id) as number_of_comments, -coalesce(sum(pl.score), 0) as score, -count (case when pl.score = 1 then 1 else null end) as upvotes, -count (case when pl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(pl.score) , 0), - ( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end - ) -) as hot_rank, -( - case when (p.published < ('now'::timestamp - '1 month'::interval)) then p.published -- Prevents necro-bumps - else greatest(c.recent_comment_time, p.published) - end -) as newest_activity_time -from post p -left join post_like pl on p.id = pl.post_id -left join ( - select post_id, - max(published) as recent_comment_time - from comment - group by 1 -) c on p.id = c.post_id -group by p.id, c.recent_comment_time; - -create materialized view post_aggregates_mview as select * from post_aggregates_view; - -create unique index idx_post_aggregates_mview_id on post_aggregates_mview (id); - -create view post_view as -with all_post as ( - select - pa.* - from post_aggregates_view pa +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + ( + SELECT + u.banned + FROM + user_ u + WHERE + p.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb + WHERE + p.creator_id = cb.user_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + actor_id + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_local, + ( + SELECT + name + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + p.creator_id = user_.id) AS creator_avatar, + ( + SELECT + actor_id + FROM + community + WHERE + p.community_id = community.id) AS community_actor_id, + ( + SELECT + local + FROM + community + WHERE + p.community_id = community.id) AS community_local, + ( + SELECT + name + FROM + community + WHERE + p.community_id = community.id) AS community_name, + ( + SELECT + removed + FROM + community c + WHERE + p.community_id = c.id) AS community_removed, + ( + SELECT + deleted + FROM + community c + WHERE + p.community_id = c.id) AS community_deleted, + ( + SELECT + nsfw + FROM + community c + WHERE + p.community_id = c.id) AS community_nsfw, + ( + SELECT + count(*) + FROM + comment + WHERE + comment.post_id = p.id) AS number_of_comments, + coalesce(sum(pl.score), 0) AS score, + count( + CASE WHEN pl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN pl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(pl.score), 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published -- Prevents necro-bumps + ELSE + greatest (c.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + LEFT JOIN ( + SELECT + post_id, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + 1) c ON p.id = c.post_id +GROUP BY + p.id, + c.recent_comment_time; + +CREATE MATERIALIZED VIEW post_aggregates_mview AS +SELECT + * +FROM + post_aggregates_view; + +CREATE UNIQUE INDEX idx_post_aggregates_mview_id ON post_aggregates_mview (id); + +CREATE VIEW post_view AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_view pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -create view post_mview as -with all_post as ( - select - pa.* - from post_aggregates_mview pa +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +CREATE VIEW post_mview AS +with all_post AS ( + SELECT + pa.* + FROM + post_aggregates_mview pa ) -select -ap.*, -u.id as user_id, -coalesce(pl.score, 0) as my_vote, -(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, -(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, -(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved -from user_ u -cross join all_post ap -left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id - -union all - -select -ap.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from all_post ap -; - -drop trigger refresh_post on post; -create trigger refresh_post -after insert or update or delete or truncate -on post -for each statement -execute procedure refresh_post(); - -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - refresh materialized view concurrently post_aggregates_mview; - refresh materialized view concurrently user_mview; - return null; -end $$; - +SELECT + ap.*, + u.id AS user_id, + coalesce(pl.score, 0) AS my_vote, + ( + SELECT + cf.id::bool + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND cf.community_id = ap.community_id) AS subscribed, + ( + SELECT + pr.id::bool + FROM + post_read pr + WHERE + u.id = pr.user_id + AND pr.post_id = ap.id) AS read, + ( + SELECT + ps.id::bool + FROM + post_saved ps + WHERE + u.id = ps.user_id + AND ps.post_id = ap.id) AS saved +FROM + user_ u + CROSS JOIN all_post ap + LEFT JOIN post_like pl ON u.id = pl.user_id + AND ap.id = pl.post_id + UNION ALL + SELECT + ap.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved + FROM + all_post ap; + +DROP TRIGGER refresh_post ON post; + +CREATE TRIGGER refresh_post + AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON post + FOR EACH statement + EXECUTE PROCEDURE refresh_post (); + +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + REFRESH MATERIALIZED VIEW CONCURRENTLY post_aggregates_mview; + REFRESH MATERIALIZED VIEW CONCURRENTLY user_mview; + RETURN NULL; +END +$$; -- User mention, comment, reply -drop view user_mention_view; -drop view comment_view; -drop view comment_aggregates_view; +DROP VIEW user_mention_view; --- reply and comment view -create view comment_aggregates_view as -select -c.*, -(select community_id from post p where p.id = c.post_id), -(select co.actor_id from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_actor_id, -(select co.local from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_local, -(select co.name from post p, community co where p.id = c.post_id and p.community_id = co.id) as community_name, -(select u.banned from user_ u where c.creator_id = u.id) as banned, -(select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community, -(select actor_id from user_ where c.creator_id = user_.id) as creator_actor_id, -(select local from user_ where c.creator_id = user_.id) as creator_local, -(select name from user_ where c.creator_id = user_.id) as creator_name, -(select avatar from user_ where c.creator_id = user_.id) as creator_avatar, -coalesce(sum(cl.score), 0) as score, -count (case when cl.score = 1 then 1 else null end) as upvotes, -count (case when cl.score = -1 then 1 else null end) as downvotes, -hot_rank(coalesce(sum(cl.score) , 0), c.published) as hot_rank -from comment c -left join comment_like cl on c.id = cl.comment_id -group by c.id; - -create materialized view comment_aggregates_mview as select * from comment_aggregates_view; - -create unique index idx_comment_aggregates_mview_id on comment_aggregates_mview (id); - -create view comment_view as -with all_comment as -( - select - ca.* - from comment_aggregates_view ca -) +DROP VIEW comment_view; -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +DROP VIEW comment_aggregates_view; -union all - -select +-- reply and comment view +CREATE VIEW comment_aggregates_view AS +SELECT + c.*, + ( + SELECT + community_id + FROM + post p + WHERE + p.id = c.post_id), ( + SELECT + co.actor_id + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_actor_id, + ( + SELECT + co.local + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_local, + ( + SELECT + co.name + FROM + post p, + community co + WHERE + p.id = c.post_id + AND p.community_id = co.id) AS community_name, + ( + SELECT + u.banned + FROM + user_ u + WHERE + c.creator_id = u.id) AS banned, + ( + SELECT + cb.id::bool + FROM + community_user_ban cb, + post p + WHERE + c.creator_id = cb.user_id + AND p.id = c.post_id + AND p.community_id = cb.community_id) AS banned_from_community, + ( + SELECT + actor_id + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_actor_id, + ( + SELECT + local + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_local, + ( + SELECT + name + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ + WHERE + c.creator_id = user_.id) AS creator_avatar, + coalesce(sum(cl.score), 0) AS score, + count( + CASE WHEN cl.score = 1 THEN + 1 + ELSE + NULL + END) AS upvotes, + count( + CASE WHEN cl.score = - 1 THEN + 1 + ELSE + NULL + END) AS downvotes, + hot_rank (coalesce(sum(cl.score), 0), c.published) AS hot_rank +FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + c.id; + +CREATE MATERIALIZED VIEW comment_aggregates_mview AS +SELECT + * +FROM + comment_aggregates_view; + +CREATE UNIQUE INDEX idx_comment_aggregates_mview_id ON comment_aggregates_mview (id); + +CREATE VIEW comment_view AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_view ca +) +SELECT ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; - -create view comment_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; + +CREATE VIEW comment_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select -ac.*, -u.id as user_id, -coalesce(cl.score, 0) as my_vote, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.community_id = cf.community_id) as subscribed, -(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id - -union all - -select +SELECT ac.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from all_comment ac -; + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.community_id = cf.community_id) AS subscribed, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + UNION ALL + SELECT + ac.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved + FROM + all_comment ac; -- Do the reply_view referencing the comment_mview -create view reply_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_mview cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_mview cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -444,23 +833,36 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; - - -create view user_mention_mview as -with all_comment as -( - select - ca.* - from comment_aggregates_mview ca + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + +CREATE VIEW user_mention_mview AS +with all_comment AS ( + SELECT + ca.* + FROM + comment_aggregates_mview ca ) - -select +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -484,22 +886,41 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join all_comment ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN all_comment ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -523,13 +944,25 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from all_comment ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + all_comment ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; diff --git a/migrations/2020-06-30-135809_remove_mat_views/up.sql b/migrations/2020-06-30-135809_remove_mat_views/up.sql index bd792a8b..0c633597 100644 --- a/migrations/2020-06-30-135809_remove_mat_views/up.sql +++ b/migrations/2020-06-30-135809_remove_mat_views/up.sql @@ -1,301 +1,399 @@ -- Drop the mviews -drop view post_mview; -drop materialized view user_mview; -drop view community_mview; -drop materialized view private_message_mview; -drop view user_mention_mview; -drop view reply_view; -drop view comment_mview; -drop materialized view post_aggregates_mview; -drop materialized view community_aggregates_mview; -drop materialized view comment_aggregates_mview; -drop trigger refresh_private_message on private_message; +DROP VIEW post_mview; + +DROP MATERIALIZED VIEW user_mview; + +DROP VIEW community_mview; + +DROP MATERIALIZED VIEW private_message_mview; + +DROP VIEW user_mention_mview; + +DROP VIEW reply_view; + +DROP VIEW comment_mview; + +DROP MATERIALIZED VIEW post_aggregates_mview; + +DROP MATERIALIZED VIEW community_aggregates_mview; + +DROP MATERIALIZED VIEW comment_aggregates_mview; + +DROP TRIGGER refresh_private_message ON private_message; -- User -drop view user_view; -create view user_view as -select - u.id, - u.actor_id, - u.name, - u.avatar, - u.email, - u.matrix_user_id, - u.bio, - u.local, - u.admin, - u.banned, - u.show_avatars, - u.send_notifications_to_email, - u.published, - coalesce(pd.posts, 0) as number_of_posts, - coalesce(pd.score, 0) as post_score, - coalesce(cd.comments, 0) as number_of_comments, - coalesce(cd.score, 0) as comment_score -from user_ u -left join ( - select - p.creator_id as creator_id, - count(distinct p.id) as posts, - sum(pl.score) as score - from post p - join post_like pl on p.id = pl.post_id - group by p.creator_id -) pd on u.id = pd.creator_id -left join ( - select - c.creator_id, - count(distinct c.id) as comments, - sum(cl.score) as score - from comment c - join comment_like cl on c.id = cl.comment_id - group by c.creator_id -) cd on u.id = cd.creator_id; - - -create table user_fast as select * from user_view; -alter table user_fast add primary key (id); - -drop trigger refresh_user on user_; - -create trigger refresh_user -after insert or update or delete -on user_ -for each row -execute procedure refresh_user(); - --- Sample insert +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + u.id, + u.actor_id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.bio, + u.local, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + coalesce(pd.posts, 0) AS number_of_posts, + coalesce(pd.score, 0) AS post_score, + coalesce(cd.comments, 0) AS number_of_comments, + coalesce(cd.score, 0) AS comment_score +FROM + user_ u + LEFT JOIN ( + SELECT + p.creator_id AS creator_id, + count(DISTINCT p.id) AS posts, + sum(pl.score) AS score + FROM + post p + JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.creator_id) pd ON u.id = pd.creator_id + LEFT JOIN ( + SELECT + c.creator_id, + count(DISTINCT c.id) AS comments, + sum(cl.score) AS score + FROM + comment c + JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.creator_id) cd ON u.id = cd.creator_id; + +CREATE TABLE user_fast AS +SELECT + * +FROM + user_view; + +ALTER TABLE user_fast + ADD PRIMARY KEY (id); + +DROP TRIGGER refresh_user ON user_; + +CREATE TRIGGER refresh_user + AFTER INSERT OR UPDATE OR DELETE ON user_ + FOR EACH ROW + EXECUTE PROCEDURE refresh_user (); + +-- Sample insert -- insert into user_(name, password_encrypted) values ('test_name', 'bleh'); -- Sample delete -- delete from user_ where name like 'test_name'; -- Sample update -- update user_ set avatar = 'hai' where name like 'test_name'; -create or replace function refresh_user() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from user_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from user_fast where id = OLD.id; - insert into user_fast select * from user_view where id = NEW.id; - - -- Refresh post_fast, cause of user info changes - delete from post_aggregates_fast where creator_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where creator_id = NEW.id; - - delete from comment_aggregates_fast where creator_id = NEW.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where creator_id = NEW.id; - - ELSIF (TG_OP = 'INSERT') THEN - insert into user_fast select * from user_view where id = NEW.id; - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id; + -- Refresh post_fast, cause of user info changes + DELETE FROM post_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + creator_id = NEW.id; + DELETE FROM comment_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + creator_id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; -- Post -- Redoing the views : Credit eiknat -drop view post_view; -drop view post_aggregates_view; - -create view post_aggregates_view as -select - p.*, - -- creator details - u.actor_id as creator_actor_id, - u."local" as creator_local, - u."name" as creator_name, - u.avatar as creator_avatar, - u.banned as banned, - cb.id::bool as banned_from_community, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.removed as community_removed, - c.deleted as community_deleted, - c.nsfw as community_nsfw, - -- post score data/comment count - coalesce(ct.comments, 0) as number_of_comments, - coalesce(pl.score, 0) as score, - coalesce(pl.upvotes, 0) as upvotes, - coalesce(pl.downvotes, 0) as downvotes, - hot_rank( - coalesce(pl.score , 0), ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) - ) as hot_rank, - ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) as newest_activity_time -from post p -left join user_ u on p.creator_id = u.id -left join community_user_ban cb on p.creator_id = cb.user_id and p.community_id = cb.community_id -left join community c on p.community_id = c.id -left join ( - select - post_id, - count(*) as comments, - max(published) as recent_comment_time - from comment - group by post_id -) ct on ct.post_id = p.id -left join ( - select - post_id, - sum(score) as score, - sum(score) filter (where score = 1) as upvotes, - -sum(score) filter (where score = -1) as downvotes - from post_like - group by post_id -) pl on pl.post_id = p.id -order by p.id; - -create view post_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_view pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_view pav; +DROP VIEW post_view; + +DROP VIEW post_aggregates_view; + +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + -- creator details + u.actor_id AS creator_actor_id, + u."local" AS creator_local, + u."name" AS creator_name, + u.avatar AS creator_avatar, + u.banned AS banned, + cb.id::bool AS banned_from_community, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.removed AS community_removed, + c.deleted AS community_deleted, + c.nsfw AS community_nsfw, + -- post score data/comment count + coalesce(ct.comments, 0) AS number_of_comments, + coalesce(pl.score, 0) AS score, + coalesce(pl.upvotes, 0) AS upvotes, + coalesce(pl.downvotes, 0) AS downvotes, + hot_rank (coalesce(pl.score, 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN user_ u ON p.creator_id = u.id + LEFT JOIN community_user_ban cb ON p.creator_id = cb.user_id + AND p.community_id = cb.community_id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN ( + SELECT + post_id, + count(*) AS comments, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_id, + sum(score) AS score, + sum(score) FILTER (WHERE score = 1) AS upvotes, + - sum(score) FILTER (WHERE score = - 1) AS downvotes + FROM + post_like + GROUP BY + post_id) pl ON pl.post_id = p.id +ORDER BY + p.id; + +CREATE VIEW post_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_view pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_view pav; -- The post fast table -create table post_aggregates_fast as select * from post_aggregates_view; -alter table post_aggregates_fast add primary key (id); +CREATE TABLE post_aggregates_fast AS +SELECT + * +FROM + post_aggregates_view; + +ALTER TABLE post_aggregates_fast + ADD PRIMARY KEY (id); -- For the hot rank resorting -create index idx_post_aggregates_fast_hot_rank_published on post_aggregates_fast (hot_rank desc, published desc); - -create view post_fast_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_fast pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_fast pav; - -drop trigger refresh_post on post; - -create trigger refresh_post -after insert or update or delete -on post -for each row -execute procedure refresh_post(); +CREATE INDEX idx_post_aggregates_fast_hot_rank_published ON post_aggregates_fast (hot_rank DESC, published DESC); + +CREATE VIEW post_fast_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_fast pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_fast pav; + +DROP TRIGGER refresh_post ON post; + +CREATE TRIGGER refresh_post + AFTER INSERT OR UPDATE OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE refresh_post (); -- Sample select -- select id, name from post_fast_view where name like 'test_post' and user_id is null; --- Sample insert +-- Sample insert -- insert into post(name, creator_id, community_id) values ('test_post', 2, 2); -- Sample delete -- delete from post where name like 'test_post'; -- Sample update -- update post set community_id = 4 where name like 'test_post'; -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set hot_rank = pav.hot_rank - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; -- Community -- Redoing the views : Credit eiknat -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view community_view; -drop view community_aggregates_view; - -create view community_aggregates_view as -select +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW community_view; + +DROP VIEW community_aggregates_view; + +CREATE VIEW community_aggregates_view AS +SELECT c.id, c.name, c.title, @@ -310,302 +408,382 @@ select c.actor_id, c.local, c.last_refreshed_at, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.avatar as creator_avatar, - cat.name as category_name, - coalesce(cf.subs, 0) as number_of_subscribers, - coalesce(cd.posts, 0) as number_of_posts, - coalesce(cd.comments, 0) as number_of_comments, - hot_rank(cf.subs, c.published) as hot_rank -from community c -left join user_ u on c.creator_id = u.id -left join category cat on c.category_id = cat.id -left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - join comment ct on p.id = ct.post_id - group by p.community_id -) cd on cd.community_id = c.id -left join ( - select - community_id, - count(*) as subs - from community_follower - group by community_id -) cf on cf.community_id = c.id; - -create view community_view as -select + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.avatar AS creator_avatar, + cat.name AS category_name, + coalesce(cf.subs, 0) AS number_of_subscribers, + coalesce(cd.posts, 0) AS number_of_posts, + coalesce(cd.comments, 0) AS number_of_comments, + hot_rank (cf.subs, c.published) AS hot_rank +FROM + community c + LEFT JOIN user_ u ON c.creator_id = u.id + LEFT JOIN category cat ON c.category_id = cat.id + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_id) cf ON cf.community_id = c.id; + +CREATE VIEW community_view AS +SELECT cv.*, - us.user as user_id, - us.is_subbed::bool as subscribed -from community_aggregates_view cv -cross join lateral ( - select - u.id as user, - coalesce(cf.community_id, 0) as is_subbed - from user_ u - left join community_follower cf on u.id = cf.user_id and cf.community_id = cv.id -) as us - -union all - -select + us.user AS user_id, + us.is_subbed::bool AS subscribed +FROM + community_aggregates_view cv + CROSS JOIN LATERAL ( + SELECT + u.id AS user, + coalesce(cf.community_id, 0) AS is_subbed + FROM + user_ u + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = cv.id) AS us +UNION ALL +SELECT cv.*, - null as user_id, - null as subscribed -from community_aggregates_view cv; + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_view cv; -create view community_moderator_view as -select +CREATE VIEW community_moderator_view AS +SELECT cm.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_moderator cm -left join user_ u on cm.user_id = u.id -left join community c on cm.community_id = c.id; - -create view community_follower_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_moderator cm + LEFT JOIN user_ u ON cm.user_id = u.id + LEFT JOIN community c ON cm.community_id = c.id; + +CREATE VIEW community_follower_view AS +SELECT cf.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_follower cf -left join user_ u on cf.user_id = u.id -left join community c on cf.community_id = c.id; - -create view community_user_ban_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_follower cf + LEFT JOIN user_ u ON cf.user_id = u.id + LEFT JOIN community c ON cf.community_id = c.id; + +CREATE VIEW community_user_ban_view AS +SELECT cb.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_user_ban cb -left join user_ u on cb.user_id = u.id -left join community c on cb.community_id = c.id; + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_user_ban cb + LEFT JOIN user_ u ON cb.user_id = u.id + LEFT JOIN community c ON cb.community_id = c.id; -- The community fast table - -create table community_aggregates_fast as select * from community_aggregates_view; -alter table community_aggregates_fast add primary key (id); - -create view community_fast_view as -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join ( - select - ca.* - from community_aggregates_fast ca -) ac - -union all - -select -caf.*, -null as user_id, -null as subscribed -from community_aggregates_fast caf; - -drop trigger refresh_community on community; - -create trigger refresh_community -after insert or update or delete -on community -for each row -execute procedure refresh_community(); +CREATE TABLE community_aggregates_fast AS +SELECT + * +FROM + community_aggregates_view; + +ALTER TABLE community_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW community_fast_view AS +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + community_aggregates_fast ca) ac +UNION ALL +SELECT + caf.*, + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_fast caf; + +DROP TRIGGER refresh_community ON community; + +CREATE TRIGGER refresh_community + AFTER INSERT OR UPDATE OR DELETE ON community + FOR EACH ROW + EXECUTE PROCEDURE refresh_community (); -- Sample select -- select * from community_fast_view where name like 'test_community_name' and user_id is null; --- Sample insert +-- Sample insert -- insert into community(name, title, category_id, creator_id) values ('test_community_name', 'test_community_title', 1, 2); -- Sample delete -- delete from community where name like 'test_community_name'; -- Sample update -- update community set title = 'test_community_title_2' where name like 'test_community_name'; -create or replace function refresh_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from community_aggregates_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from community_aggregates_fast where id = OLD.id; - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id; - - -- Update user view due to owner changes - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update post view due to community changes - delete from post_aggregates_fast where community_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where community_id = NEW.id; - - -- TODO make sure this shows up in the users page ? - ELSIF (TG_OP = 'INSERT') THEN - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id; - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to owner changes + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update post view due to community changes + DELETE FROM post_aggregates_fast + WHERE community_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + community_id = NEW.id; + -- TODO make sure this shows up in the users page ? + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; -- Comment - -drop view user_mention_view; -drop view comment_view; -drop view comment_aggregates_view; - -create view comment_aggregates_view as -select - ct.*, - -- community details - p.community_id, - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; - -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select +DROP VIEW user_mention_view; + +DROP VIEW comment_view; + +DROP VIEW comment_aggregates_view; + +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- community details + p.community_id, + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; + +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); -- The fast view -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); - -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; + +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; -- user mention -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -633,15 +811,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; - -create view user_mention_fast_view as -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -665,26 +858,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -708,232 +920,345 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; - - -drop trigger refresh_comment on comment; - -create trigger refresh_comment -after insert or update or delete -on comment -for each row -execute procedure refresh_comment(); + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; + +DROP TRIGGER refresh_comment ON comment; + +CREATE TRIGGER refresh_comment + AFTER INSERT OR UPDATE OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE refresh_comment (); -- Sample select -- select * from comment_fast_view where content = 'test_comment' and user_id is null; --- Sample insert +-- Sample insert -- insert into comment(creator_id, post_id, content) values (2, 2, 'test_comment'); -- Sample delete -- delete from comment where content like 'test_comment'; -- Sample update -- update comment set removed = true where content like 'test_comment'; -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id; - - -- Force the hot rank as zero on week-older posts - update post_aggregates_fast as paf - set hot_rank = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '1 week'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; - +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id; + -- Force the hot rank as zero on week-older posts + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '1 week'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; -- post_like -- select id, score, my_vote from post_fast_view where id = 29 and user_id = 4; --- Sample insert +-- Sample insert -- insert into post_like(user_id, post_id, score) values (4, 29, 1); -- Sample delete -- delete from post_like where user_id = 4 and post_id = 29; -- Sample update -- update post_like set score = -1 where user_id = 4 and post_id = 29; - -- TODO test this a LOT -create or replace function refresh_post_like() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - update post_aggregates_fast - set score = case - when (OLD.score = 1) then score - 1 - else score + 1 end, - upvotes = case - when (OLD.score = 1) then upvotes - 1 - else upvotes end, - downvotes = case - when (OLD.score = -1) then downvotes - 1 - else downvotes end - where id = OLD.post_id; - - ELSIF (TG_OP = 'INSERT') THEN - update post_aggregates_fast - set score = case - when (NEW.score = 1) then score + 1 - else score - 1 end, - upvotes = case - when (NEW.score = 1) then upvotes + 1 - else upvotes end, - downvotes = case - when (NEW.score = -1) then downvotes + 1 - else downvotes end - where id = NEW.post_id; - END IF; - - return null; -end $$; - -drop trigger refresh_post_like on post_like; -create trigger refresh_post_like -after insert or delete -on post_like -for each row -execute procedure refresh_post_like(); +CREATE OR REPLACE FUNCTION refresh_post_like () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + UPDATE + post_aggregates_fast + SET + score = CASE WHEN (OLD.score = 1) THEN + score - 1 + ELSE + score + 1 + END, + upvotes = CASE WHEN (OLD.score = 1) THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN (OLD.score = - 1) THEN + downvotes - 1 + ELSE + downvotes + END + WHERE + id = OLD.post_id; + ELSIF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates_fast + SET + score = CASE WHEN (NEW.score = 1) THEN + score + 1 + ELSE + score - 1 + END, + upvotes = CASE WHEN (NEW.score = 1) THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN (NEW.score = - 1) THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; + +DROP TRIGGER refresh_post_like ON post_like; + +CREATE TRIGGER refresh_post_like + AFTER INSERT OR DELETE ON post_like + FOR EACH ROW + EXECUTE PROCEDURE refresh_post_like (); -- comment_like -- select id, score, my_vote from comment_fast_view where id = 29 and user_id = 4; --- Sample insert +-- Sample insert -- insert into comment_like(user_id, comment_id, post_id, score) values (4, 29, 51, 1); -- Sample delete -- delete from comment_like where user_id = 4 and comment_id = 29; -- Sample update -- update comment_like set score = -1 where user_id = 4 and comment_id = 29; -create or replace function refresh_comment_like() -returns trigger language plpgsql -as $$ -begin - -- TODO possibly select from comment_fast to get previous scores, instead of re-fetching the views? - IF (TG_OP = 'DELETE') THEN - update comment_aggregates_fast - set score = case - when (OLD.score = 1) then score - 1 - else score + 1 end, - upvotes = case - when (OLD.score = 1) then upvotes - 1 - else upvotes end, - downvotes = case - when (OLD.score = -1) then downvotes - 1 - else downvotes end - where id = OLD.comment_id; - - ELSIF (TG_OP = 'INSERT') THEN - update comment_aggregates_fast - set score = case - when (NEW.score = 1) then score + 1 - else score - 1 end, - upvotes = case - when (NEW.score = 1) then upvotes + 1 - else upvotes end, - downvotes = case - when (NEW.score = -1) then downvotes + 1 - else downvotes end - where id = NEW.comment_id; - END IF; - - return null; -end $$; - -drop trigger refresh_comment_like on comment_like; -create trigger refresh_comment_like -after insert or delete -on comment_like -for each row -execute procedure refresh_comment_like(); +CREATE OR REPLACE FUNCTION refresh_comment_like () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- TODO possibly select from comment_fast to get previous scores, instead of re-fetching the views? + IF (TG_OP = 'DELETE') THEN + UPDATE + comment_aggregates_fast + SET + score = CASE WHEN (OLD.score = 1) THEN + score - 1 + ELSE + score + 1 + END, + upvotes = CASE WHEN (OLD.score = 1) THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN (OLD.score = - 1) THEN + downvotes - 1 + ELSE + downvotes + END + WHERE + id = OLD.comment_id; + ELSIF (TG_OP = 'INSERT') THEN + UPDATE + comment_aggregates_fast + SET + score = CASE WHEN (NEW.score = 1) THEN + score + 1 + ELSE + score - 1 + END, + upvotes = CASE WHEN (NEW.score = 1) THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN (NEW.score = - 1) THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + id = NEW.comment_id; + END IF; + RETURN NULL; +END +$$; + +DROP TRIGGER refresh_comment_like ON comment_like; + +CREATE TRIGGER refresh_comment_like + AFTER INSERT OR DELETE ON comment_like + FOR EACH ROW + EXECUTE PROCEDURE refresh_comment_like (); -- Community user ban +DROP TRIGGER refresh_community_user_ban ON community_user_ban; -drop trigger refresh_community_user_ban on community_user_ban; -create trigger refresh_community_user_ban -after insert or delete -- Note this is missing after update -on community_user_ban -for each row -execute procedure refresh_community_user_ban(); +CREATE TRIGGER refresh_community_user_ban + AFTER INSERT OR DELETE -- Note this is missing after update + ON community_user_ban + FOR EACH ROW + EXECUTE PROCEDURE refresh_community_user_ban (); -- select creator_name, banned_from_community from comment_fast_view where user_id = 4 and content = 'test_before_ban'; -- select creator_name, banned_from_community, community_id from comment_aggregates_fast where content = 'test_before_ban'; --- Sample insert +-- Sample insert -- insert into comment(creator_id, post_id, content) values (1198, 341, 'test_before_ban'); -- insert into community_user_ban(community_id, user_id) values (2, 1198); -- Sample delete -- delete from community_user_ban where user_id = 1198 and community_id = 2; -- delete from comment where content = 'test_before_ban'; -- update comment_aggregates_fast set banned_from_community = false where creator_id = 1198 and community_id = 2; -create or replace function refresh_community_user_ban() -returns trigger language plpgsql -as $$ -begin - -- TODO possibly select from comment_fast to get previous scores, instead of re-fetching the views? - IF (TG_OP = 'DELETE') THEN - update comment_aggregates_fast set banned_from_community = false where creator_id = OLD.user_id and community_id = OLD.community_id; - update post_aggregates_fast set banned_from_community = false where creator_id = OLD.user_id and community_id = OLD.community_id; - ELSIF (TG_OP = 'INSERT') THEN - update comment_aggregates_fast set banned_from_community = true where creator_id = NEW.user_id and community_id = NEW.community_id; - update post_aggregates_fast set banned_from_community = true where creator_id = NEW.user_id and community_id = NEW.community_id; - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_community_user_ban () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- TODO possibly select from comment_fast to get previous scores, instead of re-fetching the views? + IF (TG_OP = 'DELETE') THEN + UPDATE + comment_aggregates_fast + SET + banned_from_community = FALSE + WHERE + creator_id = OLD.user_id + AND community_id = OLD.community_id; + UPDATE + post_aggregates_fast + SET + banned_from_community = FALSE + WHERE + creator_id = OLD.user_id + AND community_id = OLD.community_id; + ELSIF (TG_OP = 'INSERT') THEN + UPDATE + comment_aggregates_fast + SET + banned_from_community = TRUE + WHERE + creator_id = NEW.user_id + AND community_id = NEW.community_id; + UPDATE + post_aggregates_fast + SET + banned_from_community = TRUE + WHERE + creator_id = NEW.user_id + AND community_id = NEW.community_id; + END IF; + RETURN NULL; +END +$$; -- Community follower +DROP TRIGGER refresh_community_follower ON community_follower; + +CREATE TRIGGER refresh_community_follower + AFTER INSERT OR DELETE -- Note this is missing after update + ON community_follower + FOR EACH ROW + EXECUTE PROCEDURE refresh_community_follower (); + +CREATE OR REPLACE FUNCTION refresh_community_follower () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates_fast + SET + number_of_subscribers = number_of_subscribers - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'INSERT') THEN + UPDATE + community_aggregates_fast + SET + number_of_subscribers = number_of_subscribers + 1 + WHERE + id = NEW.community_id; + END IF; + RETURN NULL; +END +$$; -drop trigger refresh_community_follower on community_follower; -create trigger refresh_community_follower -after insert or delete -- Note this is missing after update -on community_follower -for each row -execute procedure refresh_community_follower(); - -create or replace function refresh_community_follower() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - update community_aggregates_fast set number_of_subscribers = number_of_subscribers - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'INSERT') THEN - update community_aggregates_fast set number_of_subscribers = number_of_subscribers + 1 where id = NEW.community_id; - END IF; - - return null; -end $$; diff --git a/migrations/2020-07-08-202609_add_creator_published/down.sql b/migrations/2020-07-08-202609_add_creator_published/down.sql index b8e4452e..fd1ca1cb 100644 --- a/migrations/2020-07-08-202609_add_creator_published/down.sql +++ b/migrations/2020-07-08-202609_add_creator_published/down.sql @@ -1,115 +1,145 @@ -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; +DROP VIEW user_mention_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; +DROP VIEW reply_fast_view; -create view comment_aggregates_view as -select - ct.*, - -- community details - p.community_id, - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; +DROP VIEW comment_fast_view; -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +DROP VIEW comment_view; -union all +DROP VIEW user_mention_fast_view; -select - cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- community details + p.community_id, + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); -union all +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; -select +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -137,15 +167,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_fast_view as -select +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -169,26 +214,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -212,177 +276,220 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; -- add creator_published to the post view -drop view post_fast_view; -drop table post_aggregates_fast; -drop view post_view; -drop view post_aggregates_view; +DROP VIEW post_fast_view; + +DROP TABLE post_aggregates_fast; -create view post_aggregates_view as -select - p.*, - -- creator details - u.actor_id as creator_actor_id, - u."local" as creator_local, - u."name" as creator_name, - u.avatar as creator_avatar, - u.banned as banned, - cb.id::bool as banned_from_community, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.removed as community_removed, - c.deleted as community_deleted, - c.nsfw as community_nsfw, - -- post score data/comment count - coalesce(ct.comments, 0) as number_of_comments, - coalesce(pl.score, 0) as score, - coalesce(pl.upvotes, 0) as upvotes, - coalesce(pl.downvotes, 0) as downvotes, - hot_rank( - coalesce(pl.score , 0), ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) - ) as hot_rank, - ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) as newest_activity_time -from post p -left join user_ u on p.creator_id = u.id -left join community_user_ban cb on p.creator_id = cb.user_id and p.community_id = cb.community_id -left join community c on p.community_id = c.id -left join ( - select - post_id, - count(*) as comments, - max(published) as recent_comment_time - from comment - group by post_id -) ct on ct.post_id = p.id -left join ( - select - post_id, - sum(score) as score, - sum(score) filter (where score = 1) as upvotes, - -sum(score) filter (where score = -1) as downvotes - from post_like - group by post_id -) pl on pl.post_id = p.id -order by p.id; +DROP VIEW post_view; -create view post_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_view pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us +DROP VIEW post_aggregates_view; -union all +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + -- creator details + u.actor_id AS creator_actor_id, + u."local" AS creator_local, + u."name" AS creator_name, + u.avatar AS creator_avatar, + u.banned AS banned, + cb.id::bool AS banned_from_community, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.removed AS community_removed, + c.deleted AS community_deleted, + c.nsfw AS community_nsfw, + -- post score data/comment count + coalesce(ct.comments, 0) AS number_of_comments, + coalesce(pl.score, 0) AS score, + coalesce(pl.upvotes, 0) AS upvotes, + coalesce(pl.downvotes, 0) AS downvotes, + hot_rank (coalesce(pl.score, 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN user_ u ON p.creator_id = u.id + LEFT JOIN community_user_ban cb ON p.creator_id = cb.user_id + AND p.community_id = cb.community_id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN ( + SELECT + post_id, + count(*) AS comments, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_id, + sum(score) AS score, + sum(score) FILTER (WHERE score = 1) AS upvotes, + - sum(score) FILTER (WHERE score = - 1) AS downvotes + FROM + post_like + GROUP BY + post_id) pl ON pl.post_id = p.id +ORDER BY + p.id; -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_view pav; +CREATE VIEW post_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_view pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_view pav; -create table post_aggregates_fast as select * from post_aggregates_view; -alter table post_aggregates_fast add primary key (id); +CREATE TABLE post_aggregates_fast AS +SELECT + * +FROM + post_aggregates_view; -create view post_fast_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_fast pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us +ALTER TABLE post_aggregates_fast + ADD PRIMARY KEY (id); -union all +CREATE VIEW post_fast_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_fast pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_fast pav; -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_fast pav; \ No newline at end of file diff --git a/migrations/2020-07-08-202609_add_creator_published/up.sql b/migrations/2020-07-08-202609_add_creator_published/up.sql index 1f2b59ea..6d3ff57d 100644 --- a/migrations/2020-07-08-202609_add_creator_published/up.sql +++ b/migrations/2020-07-08-202609_add_creator_published/up.sql @@ -1,116 +1,146 @@ -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; +DROP VIEW user_mention_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; +DROP VIEW reply_fast_view; -create view comment_aggregates_view as -select - ct.*, - -- community details - p.community_id, - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; +DROP VIEW comment_fast_view; -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +DROP VIEW comment_view; -union all +DROP VIEW user_mention_fast_view; -select - cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- community details + p.community_id, + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); -union all +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; -select +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -138,15 +168,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_fast_view as -select +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -170,26 +215,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -213,178 +277,221 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; -- add creator_published to the post view -drop view post_fast_view; -drop table post_aggregates_fast; -drop view post_view; -drop view post_aggregates_view; +DROP VIEW post_fast_view; + +DROP TABLE post_aggregates_fast; -create view post_aggregates_view as -select - p.*, - -- creator details - u.actor_id as creator_actor_id, - u."local" as creator_local, - u."name" as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - u.banned as banned, - cb.id::bool as banned_from_community, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.removed as community_removed, - c.deleted as community_deleted, - c.nsfw as community_nsfw, - -- post score data/comment count - coalesce(ct.comments, 0) as number_of_comments, - coalesce(pl.score, 0) as score, - coalesce(pl.upvotes, 0) as upvotes, - coalesce(pl.downvotes, 0) as downvotes, - hot_rank( - coalesce(pl.score , 0), ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) - ) as hot_rank, - ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) as newest_activity_time -from post p -left join user_ u on p.creator_id = u.id -left join community_user_ban cb on p.creator_id = cb.user_id and p.community_id = cb.community_id -left join community c on p.community_id = c.id -left join ( - select - post_id, - count(*) as comments, - max(published) as recent_comment_time - from comment - group by post_id -) ct on ct.post_id = p.id -left join ( - select - post_id, - sum(score) as score, - sum(score) filter (where score = 1) as upvotes, - -sum(score) filter (where score = -1) as downvotes - from post_like - group by post_id -) pl on pl.post_id = p.id -order by p.id; +DROP VIEW post_view; -create view post_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_view pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us +DROP VIEW post_aggregates_view; -union all +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + -- creator details + u.actor_id AS creator_actor_id, + u."local" AS creator_local, + u."name" AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + u.banned AS banned, + cb.id::bool AS banned_from_community, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.removed AS community_removed, + c.deleted AS community_deleted, + c.nsfw AS community_nsfw, + -- post score data/comment count + coalesce(ct.comments, 0) AS number_of_comments, + coalesce(pl.score, 0) AS score, + coalesce(pl.upvotes, 0) AS upvotes, + coalesce(pl.downvotes, 0) AS downvotes, + hot_rank (coalesce(pl.score, 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN user_ u ON p.creator_id = u.id + LEFT JOIN community_user_ban cb ON p.creator_id = cb.user_id + AND p.community_id = cb.community_id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN ( + SELECT + post_id, + count(*) AS comments, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_id, + sum(score) AS score, + sum(score) FILTER (WHERE score = 1) AS upvotes, + - sum(score) FILTER (WHERE score = - 1) AS downvotes + FROM + post_like + GROUP BY + post_id) pl ON pl.post_id = p.id +ORDER BY + p.id; -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_view pav; +CREATE VIEW post_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_view pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_view pav; -create table post_aggregates_fast as select * from post_aggregates_view; -alter table post_aggregates_fast add primary key (id); +CREATE TABLE post_aggregates_fast AS +SELECT + * +FROM + post_aggregates_view; -create view post_fast_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_fast pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us +ALTER TABLE post_aggregates_fast + ADD PRIMARY KEY (id); -union all +CREATE VIEW post_fast_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_fast pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_fast pav; -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_fast pav; \ No newline at end of file diff --git a/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql b/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql index b7c9d51e..b29521b4 100644 --- a/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql +++ b/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql @@ -1,116 +1,146 @@ -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; +DROP VIEW user_mention_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; +DROP VIEW reply_fast_view; -create view comment_aggregates_view as -select - ct.*, - -- community details - p.community_id, - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; +DROP VIEW comment_fast_view; -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +DROP VIEW comment_view; -union all +DROP VIEW user_mention_fast_view; -select - cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- community details + p.community_id, + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); -union all +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; -select +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -138,15 +168,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_fast_view as -select +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -170,26 +215,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -213,37 +277,60 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; \ No newline at end of file +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; + diff --git a/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql b/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql index 4cfa7edb..aef42733 100644 --- a/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql +++ b/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql @@ -1,118 +1,148 @@ -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; +DROP VIEW user_mention_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; +DROP VIEW reply_fast_view; -create view comment_aggregates_view as -select - ct.*, - -- post details - p."name" as post_name, - p.community_id, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; +DROP VIEW comment_fast_view; -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +DROP VIEW comment_view; -union all +DROP VIEW user_mention_fast_view; -select - cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- post details + p."name" AS post_name, + p.community_id, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); -union all +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; -select +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; -create view user_mention_view as -select +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -141,15 +171,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; -create view user_mention_fast_view as -select +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -174,26 +219,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -218,37 +282,60 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; \ No newline at end of file +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; + diff --git a/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/down.sql b/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/down.sql index 7a4f2e2f..e74da33d 100644 --- a/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/down.sql +++ b/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/down.sql @@ -1,20 +1,34 @@ +ALTER TABLE community + ALTER COLUMN actor_id SET NOT NULL; -alter table community alter column actor_id set not null; -alter table community alter column actor_id set default 'http://fake.com'; -alter table user_ alter column actor_id set not null; -alter table user_ alter column actor_id set default 'http://fake.com'; +ALTER TABLE community + ALTER COLUMN actor_id SET DEFAULT 'http://fake.com'; -drop function generate_unique_changeme; +ALTER TABLE user_ + ALTER COLUMN actor_id SET NOT NULL; -update community -set actor_id = 'http://fake.com' -where actor_id like 'changeme_%'; +ALTER TABLE user_ + ALTER COLUMN actor_id SET DEFAULT 'http://fake.com'; -update user_ -set actor_id = 'http://fake.com' -where actor_id like 'changeme_%'; +DROP FUNCTION generate_unique_changeme; -drop index idx_user_lower_actor_id; -create unique index idx_user_name_lower_actor_id on user_ (lower(name), lower(actor_id)); +UPDATE + community +SET + actor_id = 'http://fake.com' +WHERE + actor_id LIKE 'changeme_%'; + +UPDATE + user_ +SET + actor_id = 'http://fake.com' +WHERE + actor_id LIKE 'changeme_%'; + +DROP INDEX idx_user_lower_actor_id; + +CREATE UNIQUE INDEX idx_user_name_lower_actor_id ON user_ (lower(name), lower(actor_id)); + +DROP INDEX idx_community_lower_actor_id; -drop index idx_community_lower_actor_id; diff --git a/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/up.sql b/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/up.sql index e32ed5e0..527c73b1 100644 --- a/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/up.sql +++ b/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/up.sql @@ -1,50 +1,78 @@ -- Following this issue : https://github.com/LemmyNet/lemmy/issues/957 - -- Creating a unique changeme actor_id -create or replace function generate_unique_changeme() -returns text language sql -as $$ - select 'changeme_' || string_agg (substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil (random() * 62)::integer, 1), '') - from generate_series(1, 20) +CREATE OR REPLACE FUNCTION generate_unique_changeme () + RETURNS text + LANGUAGE sql + AS $$ + SELECT + 'changeme_' || string_agg(substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil(random() * 62)::integer, 1), '') + FROM + generate_series(1, 20) $$; -- Need to delete the possible community and user dupes for ones that don't start with the fake one -- A few test inserts, to make sure this removes later dupes -- insert into community (name, title, category_id, creator_id) values ('testcom', 'another testcom', 1, 2); -delete from community a using ( - select min(id) as id, actor_id - from community - group by actor_id having count(*) > 1 -) b -where a.actor_id = b.actor_id -and a.id <> b.id; - -delete from user_ a using ( - select min(id) as id, actor_id - from user_ - group by actor_id having count(*) > 1 -) b -where a.actor_id = b.actor_id -and a.id <> b.id; +DELETE FROM community a USING ( + SELECT + min(id) AS id, + actor_id + FROM + community + GROUP BY + actor_id + HAVING + count(*) > 1) b +WHERE + a.actor_id = b.actor_id + AND a.id <> b.id; + +DELETE FROM user_ a USING ( + SELECT + min(id) AS id, + actor_id + FROM + user_ + GROUP BY + actor_id + HAVING + count(*) > 1) b +WHERE + a.actor_id = b.actor_id + AND a.id <> b.id; -- Replacing the current default on the columns, to the unique one -update community -set actor_id = generate_unique_changeme() -where actor_id = 'http://fake.com'; +UPDATE + community +SET + actor_id = generate_unique_changeme () +WHERE + actor_id = 'http://fake.com'; -update user_ -set actor_id = generate_unique_changeme() -where actor_id = 'http://fake.com'; +UPDATE + user_ +SET + actor_id = generate_unique_changeme () +WHERE + actor_id = 'http://fake.com'; -- Add the unique indexes -alter table community alter column actor_id set not null; -alter table community alter column actor_id set default generate_unique_changeme(); +ALTER TABLE community + ALTER COLUMN actor_id SET NOT NULL; + +ALTER TABLE community + ALTER COLUMN actor_id SET DEFAULT generate_unique_changeme (); -alter table user_ alter column actor_id set not null; -alter table user_ alter column actor_id set default generate_unique_changeme(); +ALTER TABLE user_ + ALTER COLUMN actor_id SET NOT NULL; + +ALTER TABLE user_ + ALTER COLUMN actor_id SET DEFAULT generate_unique_changeme (); -- Add lowercase uniqueness too -drop index idx_user_name_lower_actor_id; -create unique index idx_user_lower_actor_id on user_ (lower(actor_id)); +DROP INDEX idx_user_name_lower_actor_id; + +CREATE UNIQUE INDEX idx_user_lower_actor_id ON user_ (lower(actor_id)); + +CREATE UNIQUE INDEX idx_community_lower_actor_id ON community (lower(actor_id)); -create unique index idx_community_lower_actor_id on community (lower(actor_id)); diff --git a/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql b/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql index 8ac1a99c..cb04cdd6 100644 --- a/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql +++ b/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql @@ -1,231 +1,308 @@ -- Drops first -drop view site_view; -drop table user_fast; -drop view user_view; -drop view post_fast_view; -drop table post_aggregates_fast; -drop view post_view; -drop view post_aggregates_view; -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view community_view; -drop view community_aggregates_view; -drop view community_fast_view; -drop table community_aggregates_fast; -drop view private_message_view; -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; - -alter table site - drop column icon, - drop column banner; - -alter table community - drop column icon, - drop column banner; - -alter table user_ drop column banner; +DROP VIEW site_view; + +DROP TABLE user_fast; + +DROP VIEW user_view; + +DROP VIEW post_fast_view; + +DROP TABLE post_aggregates_fast; + +DROP VIEW post_view; + +DROP VIEW post_aggregates_view; + +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW community_view; + +DROP VIEW community_aggregates_view; + +DROP VIEW community_fast_view; + +DROP TABLE community_aggregates_fast; + +DROP VIEW private_message_view; + +DROP VIEW user_mention_view; + +DROP VIEW reply_fast_view; + +DROP VIEW comment_fast_view; + +DROP VIEW comment_view; + +DROP VIEW user_mention_fast_view; + +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; + +ALTER TABLE site + DROP COLUMN icon, + DROP COLUMN banner; + +ALTER TABLE community + DROP COLUMN icon, + DROP COLUMN banner; + +ALTER TABLE user_ + DROP COLUMN banner; -- Site -create view site_view as -select *, -(select name from user_ u where s.creator_id = u.id) as creator_name, -(select avatar from user_ u where s.creator_id = u.id) as creator_avatar, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s; +CREATE VIEW site_view AS +SELECT + *, + ( + SELECT + name + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_name, + ( + SELECT + avatar + FROM + user_ u + WHERE + s.creator_id = u.id) AS creator_avatar, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s; -- User -create view user_view as -select - u.id, - u.actor_id, - u.name, - u.avatar, - u.email, - u.matrix_user_id, - u.bio, - u.local, - u.admin, - u.banned, - u.show_avatars, - u.send_notifications_to_email, - u.published, - coalesce(pd.posts, 0) as number_of_posts, - coalesce(pd.score, 0) as post_score, - coalesce(cd.comments, 0) as number_of_comments, - coalesce(cd.score, 0) as comment_score -from user_ u -left join ( - select - p.creator_id as creator_id, - count(distinct p.id) as posts, - sum(pl.score) as score - from post p - join post_like pl on p.id = pl.post_id - group by p.creator_id -) pd on u.id = pd.creator_id -left join ( - select - c.creator_id, - count(distinct c.id) as comments, - sum(cl.score) as score - from comment c - join comment_like cl on c.id = cl.comment_id - group by c.creator_id -) cd on u.id = cd.creator_id; - -create table user_fast as select * from user_view; -alter table user_fast add primary key (id); +CREATE VIEW user_view AS +SELECT + u.id, + u.actor_id, + u.name, + u.avatar, + u.email, + u.matrix_user_id, + u.bio, + u.local, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + coalesce(pd.posts, 0) AS number_of_posts, + coalesce(pd.score, 0) AS post_score, + coalesce(cd.comments, 0) AS number_of_comments, + coalesce(cd.score, 0) AS comment_score +FROM + user_ u + LEFT JOIN ( + SELECT + p.creator_id AS creator_id, + count(DISTINCT p.id) AS posts, + sum(pl.score) AS score + FROM + post p + JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.creator_id) pd ON u.id = pd.creator_id + LEFT JOIN ( + SELECT + c.creator_id, + count(DISTINCT c.id) AS comments, + sum(cl.score) AS score + FROM + comment c + JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.creator_id) cd ON u.id = cd.creator_id; + +CREATE TABLE user_fast AS +SELECT + * +FROM + user_view; + +ALTER TABLE user_fast + ADD PRIMARY KEY (id); -- Post fast - -create view post_aggregates_view as -select - p.*, - -- creator details - u.actor_id as creator_actor_id, - u."local" as creator_local, - u."name" as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - u.banned as banned, - cb.id::bool as banned_from_community, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.removed as community_removed, - c.deleted as community_deleted, - c.nsfw as community_nsfw, - -- post score data/comment count - coalesce(ct.comments, 0) as number_of_comments, - coalesce(pl.score, 0) as score, - coalesce(pl.upvotes, 0) as upvotes, - coalesce(pl.downvotes, 0) as downvotes, - hot_rank( - coalesce(pl.score , 0), ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) - ) as hot_rank, - ( - case - when (p.published < ('now'::timestamp - '1 month'::interval)) - then p.published - else greatest(ct.recent_comment_time, p.published) - end - ) as newest_activity_time -from post p -left join user_ u on p.creator_id = u.id -left join community_user_ban cb on p.creator_id = cb.user_id and p.community_id = cb.community_id -left join community c on p.community_id = c.id -left join ( - select - post_id, - count(*) as comments, - max(published) as recent_comment_time - from comment - group by post_id -) ct on ct.post_id = p.id -left join ( - select - post_id, - sum(score) as score, - sum(score) filter (where score = 1) as upvotes, - -sum(score) filter (where score = -1) as downvotes - from post_like - group by post_id -) pl on pl.post_id = p.id -order by p.id; - -create view post_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_view pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_view pav; - -create table post_aggregates_fast as select * from post_aggregates_view; -alter table post_aggregates_fast add primary key (id); - -create view post_fast_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_fast pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_fast pav; +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + -- creator details + u.actor_id AS creator_actor_id, + u."local" AS creator_local, + u."name" AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + u.banned AS banned, + cb.id::bool AS banned_from_community, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.removed AS community_removed, + c.deleted AS community_deleted, + c.nsfw AS community_nsfw, + -- post score data/comment count + coalesce(ct.comments, 0) AS number_of_comments, + coalesce(pl.score, 0) AS score, + coalesce(pl.upvotes, 0) AS upvotes, + coalesce(pl.downvotes, 0) AS downvotes, + hot_rank (coalesce(pl.score, 0), ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END)) AS hot_rank, + ( + CASE WHEN (p.published < ('now'::timestamp - '1 month'::interval)) THEN + p.published + ELSE + greatest (ct.recent_comment_time, p.published) + END) AS newest_activity_time +FROM + post p + LEFT JOIN user_ u ON p.creator_id = u.id + LEFT JOIN community_user_ban cb ON p.creator_id = cb.user_id + AND p.community_id = cb.community_id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN ( + SELECT + post_id, + count(*) AS comments, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_id, + sum(score) AS score, + sum(score) FILTER (WHERE score = 1) AS upvotes, + - sum(score) FILTER (WHERE score = - 1) AS downvotes + FROM + post_like + GROUP BY + post_id) pl ON pl.post_id = p.id +ORDER BY + p.id; + +CREATE VIEW post_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_view pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_view pav; + +CREATE TABLE post_aggregates_fast AS +SELECT + * +FROM + post_aggregates_view; + +ALTER TABLE post_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW post_fast_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_fast pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_fast pav; -- Community -create view community_aggregates_view as -select +CREATE VIEW community_aggregates_view AS +SELECT c.id, c.name, c.title, @@ -240,250 +317,292 @@ select c.actor_id, c.local, c.last_refreshed_at, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.avatar as creator_avatar, - cat.name as category_name, - coalesce(cf.subs, 0) as number_of_subscribers, - coalesce(cd.posts, 0) as number_of_posts, - coalesce(cd.comments, 0) as number_of_comments, - hot_rank(cf.subs, c.published) as hot_rank -from community c -left join user_ u on c.creator_id = u.id -left join category cat on c.category_id = cat.id -left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - join comment ct on p.id = ct.post_id - group by p.community_id -) cd on cd.community_id = c.id -left join ( - select - community_id, - count(*) as subs - from community_follower - group by community_id -) cf on cf.community_id = c.id; - -create view community_view as -select + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.avatar AS creator_avatar, + cat.name AS category_name, + coalesce(cf.subs, 0) AS number_of_subscribers, + coalesce(cd.posts, 0) AS number_of_posts, + coalesce(cd.comments, 0) AS number_of_comments, + hot_rank (cf.subs, c.published) AS hot_rank +FROM + community c + LEFT JOIN user_ u ON c.creator_id = u.id + LEFT JOIN category cat ON c.category_id = cat.id + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_id) cf ON cf.community_id = c.id; + +CREATE VIEW community_view AS +SELECT cv.*, - us.user as user_id, - us.is_subbed::bool as subscribed -from community_aggregates_view cv -cross join lateral ( - select - u.id as user, - coalesce(cf.community_id, 0) as is_subbed - from user_ u - left join community_follower cf on u.id = cf.user_id and cf.community_id = cv.id -) as us - -union all - -select + us.user AS user_id, + us.is_subbed::bool AS subscribed +FROM + community_aggregates_view cv + CROSS JOIN LATERAL ( + SELECT + u.id AS user, + coalesce(cf.community_id, 0) AS is_subbed + FROM + user_ u + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = cv.id) AS us +UNION ALL +SELECT cv.*, - null as user_id, - null as subscribed -from community_aggregates_view cv; + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_view cv; -create view community_moderator_view as -select +CREATE VIEW community_moderator_view AS +SELECT cm.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_moderator cm -left join user_ u on cm.user_id = u.id -left join community c on cm.community_id = c.id; - -create view community_follower_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_moderator cm + LEFT JOIN user_ u ON cm.user_id = u.id + LEFT JOIN community c ON cm.community_id = c.id; + +CREATE VIEW community_follower_view AS +SELECT cf.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_follower cf -left join user_ u on cf.user_id = u.id -left join community c on cf.community_id = c.id; - -create view community_user_ban_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_follower cf + LEFT JOIN user_ u ON cf.user_id = u.id + LEFT JOIN community c ON cf.community_id = c.id; + +CREATE VIEW community_user_ban_view AS +SELECT cb.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name -from community_user_ban cb -left join user_ u on cb.user_id = u.id -left join community c on cb.community_id = c.id; + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name +FROM + community_user_ban cb + LEFT JOIN user_ u ON cb.user_id = u.id + LEFT JOIN community c ON cb.community_id = c.id; -- The community fast table - -create table community_aggregates_fast as select * from community_aggregates_view; -alter table community_aggregates_fast add primary key (id); - -create view community_fast_view as -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join ( - select - ca.* - from community_aggregates_fast ca -) ac - -union all - -select -caf.*, -null as user_id, -null as subscribed -from community_aggregates_fast caf; - +CREATE TABLE community_aggregates_fast AS +SELECT + * +FROM + community_aggregates_view; + +ALTER TABLE community_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW community_fast_view AS +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + community_aggregates_fast ca) ac +UNION ALL +SELECT + caf.*, + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_fast caf; -- Private message -create view private_message_view as -select -pm.*, -u.name as creator_name, -u.avatar as creator_avatar, -u.actor_id as creator_actor_id, -u.local as creator_local, -u2.name as recipient_name, -u2.avatar as recipient_avatar, -u2.actor_id as recipient_actor_id, -u2.local as recipient_local -from private_message pm -inner join user_ u on u.id = pm.creator_id -inner join user_ u2 on u2.id = pm.recipient_id; - +CREATE VIEW private_message_view AS +SELECT + pm.*, + u.name AS creator_name, + u.avatar AS creator_avatar, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u2.name AS recipient_name, + u2.avatar AS recipient_avatar, + u2.actor_id AS recipient_actor_id, + u2.local AS recipient_local +FROM + private_message pm + INNER JOIN user_ u ON u.id = pm.creator_id + INNER JOIN user_ u2 ON u2.id = pm.recipient_id; -- Comments, mentions, replies - -create view comment_aggregates_view as -select - ct.*, - -- post details - p."name" as post_name, - p.community_id, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.published as creator_published, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; - -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- post details + p."name" AS post_name, + p.community_id, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.published AS creator_published, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 0), ct.published) AS hot_rank +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; + +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); + +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; + +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); - -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); - -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; - -create view user_mention_view as -select + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; + +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -512,15 +631,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; - -create view user_mention_fast_view as -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -545,26 +679,45 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -589,116 +742,204 @@ select ac.upvotes, ac.downvotes, ac.hot_rank, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; -- redoing the triggers -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set hot_rank = pav.hot_rank - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id; - - -- Force the hot rank as zero on week-older posts - update post_aggregates_fast as paf - set hot_rank = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '1 week'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id; + -- Force the hot rank as zero on week-older posts + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '1 week'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; + diff --git a/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql b/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql index 97f35fb0..7293de20 100644 --- a/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql +++ b/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql @@ -5,243 +5,305 @@ -- Community Banner -- User Banner (User avatar is already there) -- User preferred name (already in table, needs to be added to view) - -- It also adds hot_rank_active to post_view - -alter table site - add column icon text, - add column banner text; - -alter table community - add column icon text, - add column banner text; - -alter table user_ add column banner text; - -drop view site_view; -create view site_view as -select s.*, -u.name as creator_name, -u.preferred_username as creator_preferred_username, -u.avatar as creator_avatar, -(select count(*) from user_) as number_of_users, -(select count(*) from post) as number_of_posts, -(select count(*) from comment) as number_of_comments, -(select count(*) from community) as number_of_communities -from site s -left join user_ u on s.creator_id = u.id; +ALTER TABLE site + ADD COLUMN icon text, + ADD COLUMN banner text; + +ALTER TABLE community + ADD COLUMN icon text, + ADD COLUMN banner text; + +ALTER TABLE user_ + ADD COLUMN banner text; + +DROP VIEW site_view; + +CREATE VIEW site_view AS +SELECT + s.*, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.avatar AS creator_avatar, + ( + SELECT + count(*) + FROM + user_) AS number_of_users, + ( + SELECT + count(*) + FROM + post) AS number_of_posts, + ( + SELECT + count(*) + FROM + comment) AS number_of_comments, + ( + SELECT + count(*) + FROM + community) AS number_of_communities +FROM + site s + LEFT JOIN user_ u ON s.creator_id = u.id; -- User -drop table user_fast; -drop view user_view; -create view user_view as -select - u.id, - u.actor_id, - u.name, - u.preferred_username, - u.avatar, - u.banner, - u.email, - u.matrix_user_id, - u.bio, - u.local, - u.admin, - u.banned, - u.show_avatars, - u.send_notifications_to_email, - u.published, - coalesce(pd.posts, 0) as number_of_posts, - coalesce(pd.score, 0) as post_score, - coalesce(cd.comments, 0) as number_of_comments, - coalesce(cd.score, 0) as comment_score -from user_ u -left join ( - select - p.creator_id as creator_id, - count(distinct p.id) as posts, - sum(pl.score) as score - from post p - join post_like pl on p.id = pl.post_id - group by p.creator_id -) pd on u.id = pd.creator_id -left join ( - select - c.creator_id, - count(distinct c.id) as comments, - sum(cl.score) as score - from comment c - join comment_like cl on c.id = cl.comment_id - group by c.creator_id -) cd on u.id = cd.creator_id; - -create table user_fast as select * from user_view; -alter table user_fast add primary key (id); +DROP TABLE user_fast; + +DROP VIEW user_view; + +CREATE VIEW user_view AS +SELECT + u.id, + u.actor_id, + u.name, + u.preferred_username, + u.avatar, + u.banner, + u.email, + u.matrix_user_id, + u.bio, + u.local, + u.admin, + u.banned, + u.show_avatars, + u.send_notifications_to_email, + u.published, + coalesce(pd.posts, 0) AS number_of_posts, + coalesce(pd.score, 0) AS post_score, + coalesce(cd.comments, 0) AS number_of_comments, + coalesce(cd.score, 0) AS comment_score +FROM + user_ u + LEFT JOIN ( + SELECT + p.creator_id AS creator_id, + count(DISTINCT p.id) AS posts, + sum(pl.score) AS score + FROM + post p + JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.creator_id) pd ON u.id = pd.creator_id + LEFT JOIN ( + SELECT + c.creator_id, + count(DISTINCT c.id) AS comments, + sum(cl.score) AS score + FROM + comment c + JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.creator_id) cd ON u.id = cd.creator_id; + +CREATE TABLE user_fast AS +SELECT + * +FROM + user_view; + +ALTER TABLE user_fast + ADD PRIMARY KEY (id); -- private message -drop view private_message_view; -create view private_message_view as -select -pm.*, -u.name as creator_name, -u.preferred_username as creator_preferred_username, -u.avatar as creator_avatar, -u.actor_id as creator_actor_id, -u.local as creator_local, -u2.name as recipient_name, -u2.preferred_username as recipient_preferred_username, -u2.avatar as recipient_avatar, -u2.actor_id as recipient_actor_id, -u2.local as recipient_local -from private_message pm -inner join user_ u on u.id = pm.creator_id -inner join user_ u2 on u2.id = pm.recipient_id; +DROP VIEW private_message_view; + +CREATE VIEW private_message_view AS +SELECT + pm.*, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.avatar AS creator_avatar, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u2.name AS recipient_name, + u2.preferred_username AS recipient_preferred_username, + u2.avatar AS recipient_avatar, + u2.actor_id AS recipient_actor_id, + u2.local AS recipient_local +FROM + private_message pm + INNER JOIN user_ u ON u.id = pm.creator_id + INNER JOIN user_ u2 ON u2.id = pm.recipient_id; -- Post fast -drop view post_fast_view; -drop table post_aggregates_fast; -drop view post_view; -drop view post_aggregates_view; - -create view post_aggregates_view as -select - p.*, - -- creator details - u.actor_id as creator_actor_id, - u."local" as creator_local, - u."name" as creator_name, - u."preferred_username" as creator_preferred_username, - u.published as creator_published, - u.avatar as creator_avatar, - u.banned as banned, - cb.id::bool as banned_from_community, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.icon as community_icon, - c.removed as community_removed, - c.deleted as community_deleted, - c.nsfw as community_nsfw, - -- post score data/comment count - coalesce(ct.comments, 0) as number_of_comments, - coalesce(pl.score, 0) as score, - coalesce(pl.upvotes, 0) as upvotes, - coalesce(pl.downvotes, 0) as downvotes, - hot_rank(coalesce(pl.score, 1), p.published) as hot_rank, - hot_rank(coalesce(pl.score, 1), greatest(ct.recent_comment_time, p.published)) as hot_rank_active, - greatest(ct.recent_comment_time, p.published) as newest_activity_time -from post p -left join user_ u on p.creator_id = u.id -left join community_user_ban cb on p.creator_id = cb.user_id and p.community_id = cb.community_id -left join community c on p.community_id = c.id -left join ( - select - post_id, - count(*) as comments, - max(published) as recent_comment_time - from comment - group by post_id -) ct on ct.post_id = p.id -left join ( - select - post_id, - sum(score) as score, - sum(score) filter (where score = 1) as upvotes, - -sum(score) filter (where score = -1) as downvotes - from post_like - group by post_id -) pl on pl.post_id = p.id -order by p.id; - -create view post_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_view pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_view pav; - -create table post_aggregates_fast as select * from post_aggregates_view; -alter table post_aggregates_fast add primary key (id); +DROP VIEW post_fast_view; + +DROP TABLE post_aggregates_fast; + +DROP VIEW post_view; + +DROP VIEW post_aggregates_view; + +CREATE VIEW post_aggregates_view AS +SELECT + p.*, + -- creator details + u.actor_id AS creator_actor_id, + u."local" AS creator_local, + u."name" AS creator_name, + u."preferred_username" AS creator_preferred_username, + u.published AS creator_published, + u.avatar AS creator_avatar, + u.banned AS banned, + cb.id::bool AS banned_from_community, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.icon AS community_icon, + c.removed AS community_removed, + c.deleted AS community_deleted, + c.nsfw AS community_nsfw, + -- post score data/comment count + coalesce(ct.comments, 0) AS number_of_comments, + coalesce(pl.score, 0) AS score, + coalesce(pl.upvotes, 0) AS upvotes, + coalesce(pl.downvotes, 0) AS downvotes, + hot_rank (coalesce(pl.score, 1), p.published) AS hot_rank, + hot_rank (coalesce(pl.score, 1), greatest (ct.recent_comment_time, p.published)) AS hot_rank_active, + greatest (ct.recent_comment_time, p.published) AS newest_activity_time +FROM + post p + LEFT JOIN user_ u ON p.creator_id = u.id + LEFT JOIN community_user_ban cb ON p.creator_id = cb.user_id + AND p.community_id = cb.community_id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN ( + SELECT + post_id, + count(*) AS comments, + max(published) AS recent_comment_time + FROM + comment + GROUP BY + post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_id, + sum(score) AS score, + sum(score) FILTER (WHERE score = 1) AS upvotes, + - sum(score) FILTER (WHERE score = - 1) AS downvotes + FROM + post_like + GROUP BY + post_id) pl ON pl.post_id = p.id +ORDER BY + p.id; + +CREATE VIEW post_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_view pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_view pav; + +CREATE TABLE post_aggregates_fast AS +SELECT + * +FROM + post_aggregates_view; + +ALTER TABLE post_aggregates_fast + ADD PRIMARY KEY (id); -- For the hot rank resorting -create index idx_post_aggregates_fast_hot_rank_published on post_aggregates_fast (hot_rank desc, published desc); -create index idx_post_aggregates_fast_hot_rank_active_published on post_aggregates_fast (hot_rank_active desc, published desc); - -create view post_fast_view as -select - pav.*, - us.id as user_id, - us.user_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_read::bool as read, - us.is_saved::bool as saved -from post_aggregates_fast pav -cross join lateral ( - select - u.id, - coalesce(cf.community_id, 0) as is_subbed, - coalesce(pr.post_id, 0) as is_read, - coalesce(ps.post_id, 0) as is_saved, - coalesce(pl.score, 0) as user_vote - from user_ u - left join community_user_ban cb on u.id = cb.user_id and cb.community_id = pav.community_id - left join community_follower cf on u.id = cf.user_id and cf.community_id = pav.community_id - left join post_read pr on u.id = pr.user_id and pr.post_id = pav.id - left join post_saved ps on u.id = ps.user_id and ps.post_id = pav.id - left join post_like pl on u.id = pl.user_id and pav.id = pl.post_id -) as us - -union all - -select -pav.*, -null as user_id, -null as my_vote, -null as subscribed, -null as read, -null as saved -from post_aggregates_fast pav; +CREATE INDEX idx_post_aggregates_fast_hot_rank_published ON post_aggregates_fast (hot_rank DESC, published DESC); + +CREATE INDEX idx_post_aggregates_fast_hot_rank_active_published ON post_aggregates_fast (hot_rank_active DESC, published DESC); + +CREATE VIEW post_fast_view AS +SELECT + pav.*, + us.id AS user_id, + us.user_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_read::bool AS read, + us.is_saved::bool AS saved +FROM + post_aggregates_fast pav + CROSS JOIN LATERAL ( + SELECT + u.id, + coalesce(cf.community_id, 0) AS is_subbed, + coalesce(pr.post_id, 0) AS is_read, + coalesce(ps.post_id, 0) AS is_saved, + coalesce(pl.score, 0) AS user_vote + FROM + user_ u + LEFT JOIN community_user_ban cb ON u.id = cb.user_id + AND cb.community_id = pav.community_id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = pav.community_id + LEFT JOIN post_read pr ON u.id = pr.user_id + AND pr.post_id = pav.id + LEFT JOIN post_saved ps ON u.id = ps.user_id + AND ps.post_id = pav.id + LEFT JOIN post_like pl ON u.id = pl.user_id + AND pav.id = pl.post_id) AS us +UNION ALL +SELECT + pav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS read, + NULL AS saved +FROM + post_aggregates_fast pav; -- Community -drop view community_moderator_view; -drop view community_follower_view; -drop view community_user_ban_view; -drop view community_view; -drop view community_aggregates_view; -drop view community_fast_view; -drop table community_aggregates_fast; - -create view community_aggregates_view as -select +DROP VIEW community_moderator_view; + +DROP VIEW community_follower_view; + +DROP VIEW community_user_ban_view; + +DROP VIEW community_view; + +DROP VIEW community_aggregates_view; + +DROP VIEW community_fast_view; + +DROP TABLE community_aggregates_fast; + +CREATE VIEW community_aggregates_view AS +SELECT c.id, c.name, c.title, @@ -258,249 +320,299 @@ select c.actor_id, c.local, c.last_refreshed_at, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.preferred_username as creator_preferred_username, - u.avatar as creator_avatar, - cat.name as category_name, - coalesce(cf.subs, 0) as number_of_subscribers, - coalesce(cd.posts, 0) as number_of_posts, - coalesce(cd.comments, 0) as number_of_comments, - hot_rank(cf.subs, c.published) as hot_rank -from community c -left join user_ u on c.creator_id = u.id -left join category cat on c.category_id = cat.id -left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - join comment ct on p.id = ct.post_id - group by p.community_id -) cd on cd.community_id = c.id -left join ( - select - community_id, - count(*) as subs - from community_follower - group by community_id -) cf on cf.community_id = c.id; - -create view community_view as -select + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.avatar AS creator_avatar, + cat.name AS category_name, + coalesce(cf.subs, 0) AS number_of_subscribers, + coalesce(cd.posts, 0) AS number_of_posts, + coalesce(cd.comments, 0) AS number_of_comments, + hot_rank (cf.subs, c.published) AS hot_rank +FROM + community c + LEFT JOIN user_ u ON c.creator_id = u.id + LEFT JOIN category cat ON c.category_id = cat.id + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_id) cf ON cf.community_id = c.id; + +CREATE VIEW community_view AS +SELECT cv.*, - us.user as user_id, - us.is_subbed::bool as subscribed -from community_aggregates_view cv -cross join lateral ( - select - u.id as user, - coalesce(cf.community_id, 0) as is_subbed - from user_ u - left join community_follower cf on u.id = cf.user_id and cf.community_id = cv.id -) as us - -union all - -select + us.user AS user_id, + us.is_subbed::bool AS subscribed +FROM + community_aggregates_view cv + CROSS JOIN LATERAL ( + SELECT + u.id AS user, + coalesce(cf.community_id, 0) AS is_subbed + FROM + user_ u + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = cv.id) AS us +UNION ALL +SELECT cv.*, - null as user_id, - null as subscribed -from community_aggregates_view cv; + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_view cv; -create view community_moderator_view as -select +CREATE VIEW community_moderator_view AS +SELECT cm.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.preferred_username as user_preferred_username, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name, - c.icon as community_icon -from community_moderator cm -left join user_ u on cm.user_id = u.id -left join community c on cm.community_id = c.id; - -create view community_follower_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.preferred_username AS user_preferred_username, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name, + c.icon AS community_icon +FROM + community_moderator cm + LEFT JOIN user_ u ON cm.user_id = u.id + LEFT JOIN community c ON cm.community_id = c.id; + +CREATE VIEW community_follower_view AS +SELECT cf.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.preferred_username as user_preferred_username, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name, - c.icon as community_icon -from community_follower cf -left join user_ u on cf.user_id = u.id -left join community c on cf.community_id = c.id; - -create view community_user_ban_view as -select + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.preferred_username AS user_preferred_username, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name, + c.icon AS community_icon +FROM + community_follower cf + LEFT JOIN user_ u ON cf.user_id = u.id + LEFT JOIN community c ON cf.community_id = c.id; + +CREATE VIEW community_user_ban_view AS +SELECT cb.*, - u.actor_id as user_actor_id, - u.local as user_local, - u.name as user_name, - u.preferred_username as user_preferred_username, - u.avatar as avatar, - c.actor_id as community_actor_id, - c.local as community_local, - c.name as community_name, - c.icon as community_icon -from community_user_ban cb -left join user_ u on cb.user_id = u.id -left join community c on cb.community_id = c.id; + u.actor_id AS user_actor_id, + u.local AS user_local, + u.name AS user_name, + u.preferred_username AS user_preferred_username, + u.avatar AS avatar, + c.actor_id AS community_actor_id, + c.local AS community_local, + c.name AS community_name, + c.icon AS community_icon +FROM + community_user_ban cb + LEFT JOIN user_ u ON cb.user_id = u.id + LEFT JOIN community c ON cb.community_id = c.id; -- The community fast table - -create table community_aggregates_fast as select * from community_aggregates_view; -alter table community_aggregates_fast add primary key (id); - -create view community_fast_view as -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join ( - select - ca.* - from community_aggregates_fast ca -) ac - -union all - -select -caf.*, -null as user_id, -null as subscribed -from community_aggregates_fast caf; +CREATE TABLE community_aggregates_fast AS +SELECT + * +FROM + community_aggregates_view; + +ALTER TABLE community_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW community_fast_view AS +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + community_aggregates_fast ca) ac +UNION ALL +SELECT + caf.*, + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_fast caf; -- Comments, mentions, replies -drop view user_mention_view; -drop view reply_fast_view; -drop view comment_fast_view; -drop view comment_view; -drop view user_mention_fast_view; -drop table comment_aggregates_fast; -drop view comment_aggregates_view; - -create view comment_aggregates_view as -select - ct.*, - -- post details - p."name" as post_name, - p.community_id, - -- community details - c.actor_id as community_actor_id, - c."local" as community_local, - c."name" as community_name, - c.icon as community_icon, - -- creator details - u.banned as banned, - coalesce(cb.id, 0)::bool as banned_from_community, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.preferred_username as creator_preferred_username, - u.published as creator_published, - u.avatar as creator_avatar, - -- score details - coalesce(cl.total, 0) as score, - coalesce(cl.up, 0) as upvotes, - coalesce(cl.down, 0) as downvotes, - hot_rank(coalesce(cl.total, 1), p.published) as hot_rank, - hot_rank(coalesce(cl.total, 1), ct.published) as hot_rank_active -from comment ct -left join post p on ct.post_id = p.id -left join community c on p.community_id = c.id -left join user_ u on ct.creator_id = u.id -left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id -left join ( - select - l.comment_id as id, - sum(l.score) as total, - count(case when l.score = 1 then 1 else null end) as up, - count(case when l.score = -1 then 1 else null end) as down - from comment_like l - group by comment_id -) as cl on cl.id = ct.id; - -create or replace view comment_view as ( -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_view cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select +DROP VIEW user_mention_view; + +DROP VIEW reply_fast_view; + +DROP VIEW comment_fast_view; + +DROP VIEW comment_view; + +DROP VIEW user_mention_fast_view; + +DROP TABLE comment_aggregates_fast; + +DROP VIEW comment_aggregates_view; + +CREATE VIEW comment_aggregates_view AS +SELECT + ct.*, + -- post details + p."name" AS post_name, + p.community_id, + -- community details + c.actor_id AS community_actor_id, + c."local" AS community_local, + c."name" AS community_name, + c.icon AS community_icon, + -- creator details + u.banned AS banned, + coalesce(cb.id, 0)::bool AS banned_from_community, + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.published AS creator_published, + u.avatar AS creator_avatar, + -- score details + coalesce(cl.total, 0) AS score, + coalesce(cl.up, 0) AS upvotes, + coalesce(cl.down, 0) AS downvotes, + hot_rank (coalesce(cl.total, 1), p.published) AS hot_rank, + hot_rank (coalesce(cl.total, 1), ct.published) AS hot_rank_active +FROM + comment ct + LEFT JOIN post p ON ct.post_id = p.id + LEFT JOIN community c ON p.community_id = c.id + LEFT JOIN user_ u ON ct.creator_id = u.id + LEFT JOIN community_user_ban cb ON ct.creator_id = cb.user_id + AND p.id = ct.post_id + AND p.community_id = cb.community_id + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL + END) AS up, + count( + CASE WHEN l.score = - 1 THEN + 1 + ELSE + NULL + END) AS down + FROM + comment_like l + GROUP BY + comment_id) AS cl ON cl.id = ct.id; + +CREATE OR REPLACE VIEW comment_view AS ( + SELECT + cav.*, + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved + FROM + comment_aggregates_view cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_view cav -); - -create table comment_aggregates_fast as select * from comment_aggregates_view; -alter table comment_aggregates_fast add primary key (id); - -create view comment_fast_view as -select - cav.*, - us.user_id as user_id, - us.my_vote as my_vote, - us.is_subbed::bool as subscribed, - us.is_saved::bool as saved -from comment_aggregates_fast cav -cross join lateral ( - select - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - coalesce(cf.id, 0) as is_subbed, - coalesce(cs.id, 0) as is_saved - from user_ u - left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id - left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id - left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id -) as us - -union all - -select + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_view cav); + +CREATE TABLE comment_aggregates_fast AS +SELECT + * +FROM + comment_aggregates_view; + +ALTER TABLE comment_aggregates_fast + ADD PRIMARY KEY (id); + +CREATE VIEW comment_fast_view AS +SELECT cav.*, - null as user_id, - null as my_vote, - null as subscribed, - null as saved -from comment_aggregates_fast cav; - -create view user_mention_view as -select + us.user_id AS user_id, + us.my_vote AS my_vote, + us.is_subbed::bool AS subscribed, + us.is_saved::bool AS saved +FROM + comment_aggregates_fast cav + CROSS JOIN LATERAL ( + SELECT + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + coalesce(cf.id, 0) AS is_subbed, + coalesce(cs.id, 0) AS is_saved + FROM + user_ u + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND cav.id = cl.comment_id + LEFT JOIN comment_saved cs ON u.id = cs.user_id + AND cs.comment_id = cav.id + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cav.community_id = cf.community_id) AS us +UNION ALL +SELECT + cav.*, + NULL AS user_id, + NULL AS my_vote, + NULL AS subscribed, + NULL AS saved +FROM + comment_aggregates_fast cav; + +CREATE VIEW user_mention_view AS +SELECT c.id, - um.id as user_mention_id, + um.id AS user_mention_id, c.creator_id, c.creator_actor_id, c.creator_local, @@ -532,15 +644,30 @@ select c.my_vote, c.saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_mention um, comment_view c -where um.comment_id = c.id; - -create view user_mention_fast_view as -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_mention um, + comment_view c +WHERE + um.comment_id = c.id; + +CREATE VIEW user_mention_fast_view AS +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -568,26 +695,45 @@ select ac.downvotes, ac.hot_rank, ac.hot_rank_active, - u.id as user_id, - coalesce(cl.score, 0) as my_vote, - (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + u.id AS user_id, + coalesce(cl.score, 0) AS my_vote, + ( + SELECT + cs.id::bool + FROM + comment_saved cs + WHERE + u.id = cs.user_id + AND cs.comment_id = ac.id) AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from user_ u -cross join ( - select - ca.* - from comment_aggregates_fast ca -) ac -left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id -left join user_mention um on um.comment_id = ac.id - -union all - -select + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + comment_aggregates_fast ca) ac + LEFT JOIN comment_like cl ON u.id = cl.user_id + AND ac.id = cl.comment_id + LEFT JOIN user_mention um ON um.comment_id = ac.id +UNION ALL +SELECT ac.id, - um.id as user_mention_id, + um.id AS user_mention_id, ac.creator_id, ac.creator_actor_id, ac.creator_local, @@ -615,134 +761,227 @@ select ac.downvotes, ac.hot_rank, ac.hot_rank_active, - null as user_id, - null as my_vote, - null as saved, + NULL AS user_id, + NULL AS my_vote, + NULL AS saved, um.recipient_id, - (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id, - (select local from user_ u where u.id = um.recipient_id) as recipient_local -from comment_aggregates_fast ac -left join user_mention um on um.comment_id = ac.id -; + ( + SELECT + actor_id + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_actor_id, + ( + SELECT + local + FROM + user_ u + WHERE + u.id = um.recipient_id) AS recipient_local +FROM + comment_aggregates_fast ac + LEFT JOIN user_mention um ON um.comment_id = ac.id; -- Do the reply_view referencing the comment_fast_view -create view reply_fast_view as -with closereply as ( - select - c2.id, - c2.creator_id as sender_id, - c.creator_id as recipient_id - from comment c - inner join comment c2 on c.id = c2.parent_id - where c2.creator_id != c.creator_id - -- Do union where post is null - union - select - c.id, - c.creator_id as sender_id, - p.creator_id as recipient_id - from comment c, post p - where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +CREATE VIEW reply_fast_view AS +with closereply AS ( + SELECT + c2.id, + c2.creator_id AS sender_id, + c.creator_id AS recipient_id + FROM + comment c + INNER JOIN comment c2 ON c.id = c2.parent_id + WHERE + c2.creator_id != c.creator_id + -- Do union where post is null + UNION + SELECT + c.id, + c.creator_id AS sender_id, + p.creator_id AS recipient_id + FROM + comment c, + post p + WHERE + c.post_id = p.id + AND c.parent_id IS NULL + AND c.creator_id != p.creator_id ) -select cv.*, -closereply.recipient_id -from comment_fast_view cv, closereply -where closereply.id = cv.id -; +SELECT + cv.*, + closereply.recipient_id +FROM + comment_fast_view cv, + closereply +WHERE + closereply.id = cv.id; -- Adding hot rank active to the triggers -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set - hot_rank = pav.hot_rank, - hot_rank_active = pav.hot_rank_active - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id; - - -- Update the comment hot_ranks as of last week - update comment_aggregates_fast as caf - set - hot_rank = cav.hot_rank, - hot_rank_active = cav.hot_rank_active - from comment_aggregates_view as cav - where caf.id = cav.id and (cav.published > ('now'::timestamp - '1 week'::interval)); - - -- Update the post ranks - update post_aggregates_fast as paf - set - hot_rank = pav.hot_rank, - hot_rank_active = pav.hot_rank_active - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - - -- Force the hot rank active as zero on 2 day-older posts (necro-bump) - update post_aggregates_fast as paf - set hot_rank_active = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '2 days'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank, + hot_rank_active = pav.hot_rank_active + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id; + -- Update the comment hot_ranks as of last week + UPDATE + comment_aggregates_fast AS caf + SET + hot_rank = cav.hot_rank, + hot_rank_active = cav.hot_rank_active + FROM + comment_aggregates_view AS cav + WHERE + caf.id = cav.id + AND (cav.published > ('now'::timestamp - '1 week'::interval)); + -- Update the post ranks + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank, + hot_rank_active = pav.hot_rank_active + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + -- Force the hot rank active as zero on 2 day-older posts (necro-bump) + UPDATE + post_aggregates_fast AS paf + SET + hot_rank_active = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '2 days'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; + diff --git a/migrations/2020-08-06-205355_update_community_post_count/down.sql b/migrations/2020-08-06-205355_update_community_post_count/down.sql index 53b016c8..984f407b 100644 --- a/migrations/2020-08-06-205355_update_community_post_count/down.sql +++ b/migrations/2020-08-06-205355_update_community_post_count/down.sql @@ -1,11 +1,14 @@ -- Drop first -drop view community_view; -drop view community_aggregates_view; -drop view community_fast_view; -drop table community_aggregates_fast; +DROP VIEW community_view; -create view community_aggregates_view as -select +DROP VIEW community_aggregates_view; + +DROP VIEW community_fast_view; + +DROP TABLE community_aggregates_fast; + +CREATE VIEW community_aggregates_view AS +SELECT c.id, c.name, c.title, @@ -22,79 +25,96 @@ select c.actor_id, c.local, c.last_refreshed_at, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.preferred_username as creator_preferred_username, - u.avatar as creator_avatar, - cat.name as category_name, - coalesce(cf.subs, 0) as number_of_subscribers, - coalesce(cd.posts, 0) as number_of_posts, - coalesce(cd.comments, 0) as number_of_comments, - hot_rank(cf.subs, c.published) as hot_rank -from community c -left join user_ u on c.creator_id = u.id -left join category cat on c.category_id = cat.id -left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - join comment ct on p.id = ct.post_id - group by p.community_id -) cd on cd.community_id = c.id -left join ( - select - community_id, - count(*) as subs - from community_follower - group by community_id -) cf on cf.community_id = c.id; + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.avatar AS creator_avatar, + cat.name AS category_name, + coalesce(cf.subs, 0) AS number_of_subscribers, + coalesce(cd.posts, 0) AS number_of_posts, + coalesce(cd.comments, 0) AS number_of_comments, + hot_rank (cf.subs, c.published) AS hot_rank +FROM + community c + LEFT JOIN user_ u ON c.creator_id = u.id + LEFT JOIN category cat ON c.category_id = cat.id + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_id) cf ON cf.community_id = c.id; -create view community_view as -select +CREATE VIEW community_view AS +SELECT cv.*, - us.user as user_id, - us.is_subbed::bool as subscribed -from community_aggregates_view cv -cross join lateral ( - select - u.id as user, - coalesce(cf.community_id, 0) as is_subbed - from user_ u - left join community_follower cf on u.id = cf.user_id and cf.community_id = cv.id -) as us - -union all - -select + us.user AS user_id, + us.is_subbed::bool AS subscribed +FROM + community_aggregates_view cv + CROSS JOIN LATERAL ( + SELECT + u.id AS user, + coalesce(cf.community_id, 0) AS is_subbed + FROM + user_ u + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = cv.id) AS us +UNION ALL +SELECT cv.*, - null as user_id, - null as subscribed -from community_aggregates_view cv; + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_view cv; -- The community fast table +CREATE TABLE community_aggregates_fast AS +SELECT + * +FROM + community_aggregates_view; -create table community_aggregates_fast as select * from community_aggregates_view; -alter table community_aggregates_fast add primary key (id); - -create view community_fast_view as -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join ( - select - ca.* - from community_aggregates_fast ca -) ac +ALTER TABLE community_aggregates_fast + ADD PRIMARY KEY (id); -union all +CREATE VIEW community_fast_view AS +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + community_aggregates_fast ca) ac +UNION ALL +SELECT + caf.*, + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_fast caf; -select -caf.*, -null as user_id, -null as subscribed -from community_aggregates_fast caf; \ No newline at end of file diff --git a/migrations/2020-08-06-205355_update_community_post_count/up.sql b/migrations/2020-08-06-205355_update_community_post_count/up.sql index de5d447d..8258f5d4 100644 --- a/migrations/2020-08-06-205355_update_community_post_count/up.sql +++ b/migrations/2020-08-06-205355_update_community_post_count/up.sql @@ -1,11 +1,14 @@ -- Drop first -drop view community_view; -drop view community_aggregates_view; -drop view community_fast_view; -drop table community_aggregates_fast; +DROP VIEW community_view; -create view community_aggregates_view as -select +DROP VIEW community_aggregates_view; + +DROP VIEW community_fast_view; + +DROP TABLE community_aggregates_fast; + +CREATE VIEW community_aggregates_view AS +SELECT c.id, c.name, c.title, @@ -22,79 +25,96 @@ select c.actor_id, c.local, c.last_refreshed_at, - u.actor_id as creator_actor_id, - u.local as creator_local, - u.name as creator_name, - u.preferred_username as creator_preferred_username, - u.avatar as creator_avatar, - cat.name as category_name, - coalesce(cf.subs, 0) as number_of_subscribers, - coalesce(cd.posts, 0) as number_of_posts, - coalesce(cd.comments, 0) as number_of_comments, - hot_rank(cf.subs, c.published) as hot_rank -from community c -left join user_ u on c.creator_id = u.id -left join category cat on c.category_id = cat.id -left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - left join comment ct on p.id = ct.post_id - group by p.community_id -) cd on cd.community_id = c.id -left join ( - select - community_id, - count(*) as subs - from community_follower - group by community_id -) cf on cf.community_id = c.id; + u.actor_id AS creator_actor_id, + u.local AS creator_local, + u.name AS creator_name, + u.preferred_username AS creator_preferred_username, + u.avatar AS creator_avatar, + cat.name AS category_name, + coalesce(cf.subs, 0) AS number_of_subscribers, + coalesce(cd.posts, 0) AS number_of_posts, + coalesce(cd.comments, 0) AS number_of_comments, + hot_rank (cf.subs, c.published) AS hot_rank +FROM + community c + LEFT JOIN user_ u ON c.creator_id = u.id + LEFT JOIN category cat ON c.category_id = cat.id + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + LEFT JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_id) cf ON cf.community_id = c.id; -create view community_view as -select +CREATE VIEW community_view AS +SELECT cv.*, - us.user as user_id, - us.is_subbed::bool as subscribed -from community_aggregates_view cv -cross join lateral ( - select - u.id as user, - coalesce(cf.community_id, 0) as is_subbed - from user_ u - left join community_follower cf on u.id = cf.user_id and cf.community_id = cv.id -) as us - -union all - -select + us.user AS user_id, + us.is_subbed::bool AS subscribed +FROM + community_aggregates_view cv + CROSS JOIN LATERAL ( + SELECT + u.id AS user, + coalesce(cf.community_id, 0) AS is_subbed + FROM + user_ u + LEFT JOIN community_follower cf ON u.id = cf.user_id + AND cf.community_id = cv.id) AS us +UNION ALL +SELECT cv.*, - null as user_id, - null as subscribed -from community_aggregates_view cv; + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_view cv; -- The community fast table +CREATE TABLE community_aggregates_fast AS +SELECT + * +FROM + community_aggregates_view; -create table community_aggregates_fast as select * from community_aggregates_view; -alter table community_aggregates_fast add primary key (id); - -create view community_fast_view as -select -ac.*, -u.id as user_id, -(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed -from user_ u -cross join ( - select - ca.* - from community_aggregates_fast ca -) ac +ALTER TABLE community_aggregates_fast + ADD PRIMARY KEY (id); -union all +CREATE VIEW community_fast_view AS +SELECT + ac.*, + u.id AS user_id, + ( + SELECT + cf.id::boolean + FROM + community_follower cf + WHERE + u.id = cf.user_id + AND ac.id = cf.community_id) AS subscribed +FROM + user_ u + CROSS JOIN ( + SELECT + ca.* + FROM + community_aggregates_fast ca) ac +UNION ALL +SELECT + caf.*, + NULL AS user_id, + NULL AS subscribed +FROM + community_aggregates_fast caf; -select -caf.*, -null as user_id, -null as subscribed -from community_aggregates_fast caf; \ No newline at end of file diff --git a/migrations/2020-08-25-132005_add_unique_ap_ids/down.sql b/migrations/2020-08-25-132005_add_unique_ap_ids/down.sql index 2b43b59c..1fce04ba 100644 --- a/migrations/2020-08-25-132005_add_unique_ap_ids/down.sql +++ b/migrations/2020-08-25-132005_add_unique_ap_ids/down.sql @@ -1,27 +1,55 @@ -- Drop the uniques -alter table private_message drop constraint idx_private_message_ap_id; -alter table post drop constraint idx_post_ap_id; -alter table comment drop constraint idx_comment_ap_id; -alter table user_ drop constraint idx_user_actor_id; -alter table community drop constraint idx_community_actor_id; +ALTER TABLE private_message + DROP CONSTRAINT idx_private_message_ap_id; -alter table private_message alter column ap_id set not null; -alter table private_message alter column ap_id set default 'http://fake.com'; +ALTER TABLE post + DROP CONSTRAINT idx_post_ap_id; -alter table post alter column ap_id set not null; -alter table post alter column ap_id set default 'http://fake.com'; +ALTER TABLE comment + DROP CONSTRAINT idx_comment_ap_id; -alter table comment alter column ap_id set not null; -alter table comment alter column ap_id set default 'http://fake.com'; +ALTER TABLE user_ + DROP CONSTRAINT idx_user_actor_id; -update private_message -set ap_id = 'http://fake.com' -where ap_id like 'changeme_%'; +ALTER TABLE community + DROP CONSTRAINT idx_community_actor_id; -update post -set ap_id = 'http://fake.com' -where ap_id like 'changeme_%'; +ALTER TABLE private_message + ALTER COLUMN ap_id SET NOT NULL; + +ALTER TABLE private_message + ALTER COLUMN ap_id SET DEFAULT 'http://fake.com'; + +ALTER TABLE post + ALTER COLUMN ap_id SET NOT NULL; + +ALTER TABLE post + ALTER COLUMN ap_id SET DEFAULT 'http://fake.com'; + +ALTER TABLE comment + ALTER COLUMN ap_id SET NOT NULL; + +ALTER TABLE comment + ALTER COLUMN ap_id SET DEFAULT 'http://fake.com'; + +UPDATE + private_message +SET + ap_id = 'http://fake.com' +WHERE + ap_id LIKE 'changeme_%'; + +UPDATE + post +SET + ap_id = 'http://fake.com' +WHERE + ap_id LIKE 'changeme_%'; + +UPDATE + comment +SET + ap_id = 'http://fake.com' +WHERE + ap_id LIKE 'changeme_%'; -update comment -set ap_id = 'http://fake.com' -where ap_id like 'changeme_%'; diff --git a/migrations/2020-08-25-132005_add_unique_ap_ids/up.sql b/migrations/2020-08-25-132005_add_unique_ap_ids/up.sql index 75e81eef..22c275be 100644 --- a/migrations/2020-08-25-132005_add_unique_ap_ids/up.sql +++ b/migrations/2020-08-25-132005_add_unique_ap_ids/up.sql @@ -1,56 +1,101 @@ -- Add unique ap_id for private_message, comment, and post - -- Need to delete the possible dupes for ones that don't start with the fake one -delete from private_message a using ( - select min(id) as id, ap_id - from private_message - group by ap_id having count(*) > 1 -) b -where a.ap_id = b.ap_id -and a.id <> b.id; - -delete from post a using ( - select min(id) as id, ap_id - from post - group by ap_id having count(*) > 1 -) b -where a.ap_id = b.ap_id -and a.id <> b.id; - -delete from comment a using ( - select min(id) as id, ap_id - from comment - group by ap_id having count(*) > 1 -) b -where a.ap_id = b.ap_id -and a.id <> b.id; +DELETE FROM private_message a USING ( + SELECT + min(id) AS id, + ap_id + FROM + private_message + GROUP BY + ap_id + HAVING + count(*) > 1) b +WHERE + a.ap_id = b.ap_id + AND a.id <> b.id; + +DELETE FROM post a USING ( + SELECT + min(id) AS id, + ap_id + FROM + post + GROUP BY + ap_id + HAVING + count(*) > 1) b +WHERE + a.ap_id = b.ap_id + AND a.id <> b.id; + +DELETE FROM comment a USING ( + SELECT + min(id) AS id, + ap_id + FROM + comment + GROUP BY + ap_id + HAVING + count(*) > 1) b +WHERE + a.ap_id = b.ap_id + AND a.id <> b.id; -- Replacing the current default on the columns, to the unique one -update private_message -set ap_id = generate_unique_changeme() -where ap_id = 'http://fake.com'; +UPDATE + private_message +SET + ap_id = generate_unique_changeme () +WHERE + ap_id = 'http://fake.com'; -update post -set ap_id = generate_unique_changeme() -where ap_id = 'http://fake.com'; +UPDATE + post +SET + ap_id = generate_unique_changeme () +WHERE + ap_id = 'http://fake.com'; -update comment -set ap_id = generate_unique_changeme() -where ap_id = 'http://fake.com'; +UPDATE + comment +SET + ap_id = generate_unique_changeme () +WHERE + ap_id = 'http://fake.com'; -- Add the unique indexes -alter table private_message alter column ap_id set not null; -alter table private_message alter column ap_id set default generate_unique_changeme(); +ALTER TABLE private_message + ALTER COLUMN ap_id SET NOT NULL; + +ALTER TABLE private_message + ALTER COLUMN ap_id SET DEFAULT generate_unique_changeme (); + +ALTER TABLE post + ALTER COLUMN ap_id SET NOT NULL; + +ALTER TABLE post + ALTER COLUMN ap_id SET DEFAULT generate_unique_changeme (); -alter table post alter column ap_id set not null; -alter table post alter column ap_id set default generate_unique_changeme(); +ALTER TABLE comment + ALTER COLUMN ap_id SET NOT NULL; -alter table comment alter column ap_id set not null; -alter table comment alter column ap_id set default generate_unique_changeme(); +ALTER TABLE comment + ALTER COLUMN ap_id SET DEFAULT generate_unique_changeme (); -- Add the uniques, for user_ and community too -alter table private_message add constraint idx_private_message_ap_id unique (ap_id); -alter table post add constraint idx_post_ap_id unique (ap_id); -alter table comment add constraint idx_comment_ap_id unique (ap_id); -alter table user_ add constraint idx_user_actor_id unique (actor_id); -alter table community add constraint idx_community_actor_id unique (actor_id); +ALTER TABLE private_message + ADD CONSTRAINT idx_private_message_ap_id UNIQUE (ap_id); + +ALTER TABLE post + ADD CONSTRAINT idx_post_ap_id UNIQUE (ap_id); + +ALTER TABLE comment + ADD CONSTRAINT idx_comment_ap_id UNIQUE (ap_id); + +ALTER TABLE user_ + ADD CONSTRAINT idx_user_actor_id UNIQUE (actor_id); + +ALTER TABLE community + ADD CONSTRAINT idx_community_actor_id UNIQUE (actor_id); + diff --git a/migrations/2020-09-07-231141_add_migration_utils/down.sql b/migrations/2020-09-07-231141_add_migration_utils/down.sql index 80dc308a..bebe2856 100644 --- a/migrations/2020-09-07-231141_add_migration_utils/down.sql +++ b/migrations/2020-09-07-231141_add_migration_utils/down.sql @@ -1 +1,2 @@ -drop schema utils cascade; \ No newline at end of file +DROP SCHEMA utils CASCADE; + diff --git a/migrations/2020-09-07-231141_add_migration_utils/up.sql b/migrations/2020-09-07-231141_add_migration_utils/up.sql index 8f9552ea..7e2f794f 100644 --- a/migrations/2020-09-07-231141_add_migration_utils/up.sql +++ b/migrations/2020-09-07-231141_add_migration_utils/up.sql @@ -1,89 +1,127 @@ -create schema utils; +CREATE SCHEMA utils; -create table utils.deps_saved_ddl -( - id serial NOT NULL, - view_schema character varying(255), - view_name character varying(255), - ddl_to_run text, - CONSTRAINT deps_saved_ddl_pkey PRIMARY KEY (id) +CREATE TABLE utils.deps_saved_ddl ( + id serial NOT NULL, + view_schema character varying(255), + view_name character varying(255), + ddl_to_run text, + CONSTRAINT deps_saved_ddl_pkey PRIMARY KEY (id) ); -create or replace function utils.save_and_drop_views(p_view_schema name, p_view_name name) +CREATE OR REPLACE FUNCTION utils.save_and_drop_views (p_view_schema name, p_view_name name) RETURNS void LANGUAGE plpgsql COST 100 -AS $BODY$ + AS $BODY$ +DECLARE + v_curr record; +BEGIN + FOR v_curr IN ( + SELECT + obj_schema, + obj_name, + obj_type + FROM ( WITH RECURSIVE recursive_deps ( + obj_schema, + obj_name, + obj_type, + depth +) AS ( + SELECT + p_view_schema::name, + p_view_name, + NULL::varchar, + 0 + UNION + SELECT + dep_schema::varchar, + dep_name::varchar, + dep_type::varchar, + recursive_deps.depth + 1 + FROM ( + SELECT + ref_nsp.nspname ref_schema, + ref_cl.relname ref_name, + rwr_cl.relkind dep_type, + rwr_nsp.nspname dep_schema, + rwr_cl.relname dep_name + FROM + pg_depend dep + JOIN pg_class ref_cl ON dep.refobjid = ref_cl.oid + JOIN pg_namespace ref_nsp ON ref_cl.relnamespace = ref_nsp.oid + JOIN pg_rewrite rwr ON dep.objid = rwr.oid + JOIN pg_class rwr_cl ON rwr.ev_class = rwr_cl.oid + JOIN pg_namespace rwr_nsp ON rwr_cl.relnamespace = rwr_nsp.oid + WHERE + dep.deptype = 'n' + AND dep.classid = 'pg_rewrite'::regclass) deps + JOIN recursive_deps ON deps.ref_schema = recursive_deps.obj_schema + AND deps.ref_name = recursive_deps.obj_name + WHERE (deps.ref_schema != deps.dep_schema + OR deps.ref_name != deps.dep_name)) + SELECT + obj_schema, + obj_name, + obj_type, + depth + FROM + recursive_deps + WHERE + depth > 0) t + GROUP BY + obj_schema, + obj_name, + obj_type + ORDER BY + max(depth) DESC) + LOOP + IF v_curr.obj_type = 'v' THEN + INSERT INTO utils.deps_saved_ddl (view_schema, view_name, ddl_to_run) + SELECT + p_view_schema, + p_view_name, + 'CREATE VIEW ' || v_curr.obj_schema || '.' || v_curr.obj_name || ' AS ' || view_definition + FROM + information_schema.views + WHERE + table_schema = v_curr.obj_schema + AND table_name = v_curr.obj_name; + EXECUTE 'DROP VIEW' || ' ' || v_curr.obj_schema || '.' || v_curr.obj_name; + END IF; + END LOOP; +END; +$BODY$; -declare - v_curr record; -begin -for v_curr in -( - select obj_schema, obj_name, obj_type from - ( - with recursive recursive_deps(obj_schema, obj_name, obj_type, depth) as - ( - select p_view_schema::name, p_view_name, null::varchar, 0 - union - select dep_schema::varchar, dep_name::varchar, dep_type::varchar, recursive_deps.depth + 1 from - ( - select ref_nsp.nspname ref_schema, ref_cl.relname ref_name, - rwr_cl.relkind dep_type, - rwr_nsp.nspname dep_schema, - rwr_cl.relname dep_name - from pg_depend dep - join pg_class ref_cl on dep.refobjid = ref_cl.oid - join pg_namespace ref_nsp on ref_cl.relnamespace = ref_nsp.oid - join pg_rewrite rwr on dep.objid = rwr.oid - join pg_class rwr_cl on rwr.ev_class = rwr_cl.oid - join pg_namespace rwr_nsp on rwr_cl.relnamespace = rwr_nsp.oid - where dep.deptype = 'n' - and dep.classid = 'pg_rewrite'::regclass - ) deps - join recursive_deps on deps.ref_schema = recursive_deps.obj_schema and deps.ref_name = recursive_deps.obj_name - where (deps.ref_schema != deps.dep_schema or deps.ref_name != deps.dep_name) - ) - select obj_schema, obj_name, obj_type, depth - from recursive_deps - where depth > 0 - ) t - group by obj_schema, obj_name, obj_type - order by max(depth) desc -) loop - if v_curr.obj_type = 'v' then - insert into utils.deps_saved_ddl(view_schema, view_name, ddl_to_run) - select p_view_schema, p_view_name, 'CREATE VIEW ' || v_curr.obj_schema || '.' || v_curr.obj_name || ' AS ' || view_definition - from information_schema.views - where table_schema = v_curr.obj_schema and table_name = v_curr.obj_name; +CREATE OR REPLACE FUNCTION utils.restore_views (p_view_schema character varying, p_view_name character varying) + RETURNS void + LANGUAGE plpgsql + COST 100 + AS $BODY$ +DECLARE + v_curr record; +BEGIN + FOR v_curr IN ( + SELECT + ddl_to_run, + id + FROM + utils.deps_saved_ddl + WHERE + view_schema = p_view_schema + AND view_name = p_view_name + ORDER BY + id DESC) + LOOP + BEGIN + EXECUTE v_curr.ddl_to_run; + DELETE FROM utils.deps_saved_ddl + WHERE id = v_curr.id; + EXCEPTION + WHEN OTHERS THEN + -- keep looping, but please check for errors or remove left overs to handle manually + END; + END LOOP; +END; - execute 'DROP VIEW' || ' ' || v_curr.obj_schema || '.' || v_curr.obj_name; - end if; -end loop; -end; $BODY$; -create or replace function utils.restore_views(p_view_schema character varying, p_view_name character varying) - RETURNS void - LANGUAGE plpgsql - COST 100 -AS $BODY$ -declare - v_curr record; -begin -for v_curr in -( - select ddl_to_run, id - from utils.deps_saved_ddl - where view_schema = p_view_schema and view_name = p_view_name - order by id desc -) loop -begin - execute v_curr.ddl_to_run; - delete from utils.deps_saved_ddl where id = v_curr.id; - EXCEPTION WHEN OTHERS THEN - -- keep looping, but please check for errors or remove left overs to handle manually - end; -end loop; -end; -$BODY$; \ No newline at end of file diff --git a/migrations/2020-10-07-234221_fix_fast_triggers/down.sql b/migrations/2020-10-07-234221_fix_fast_triggers/down.sql index 6b44e8a4..5a905564 100644 --- a/migrations/2020-10-07-234221_fix_fast_triggers/down.sql +++ b/migrations/2020-10-07-234221_fix_fast_triggers/down.sql @@ -1,128 +1,245 @@ -create or replace function refresh_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from community_aggregates_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from community_aggregates_fast where id = OLD.id; - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id; - - -- Update user view due to owner changes - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update post view due to community changes - delete from post_aggregates_fast where community_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where community_id = NEW.id; - - -- TODO make sure this shows up in the users page ? - ELSIF (TG_OP = 'INSERT') THEN - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id; - END IF; - - return null; -end $$; - -create or replace function refresh_user() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from user_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from user_fast where id = OLD.id; - insert into user_fast select * from user_view where id = NEW.id; - - -- Refresh post_fast, cause of user info changes - delete from post_aggregates_fast where creator_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where creator_id = NEW.id; - - delete from comment_aggregates_fast where creator_id = NEW.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where creator_id = NEW.id; - - ELSIF (TG_OP = 'INSERT') THEN - insert into user_fast select * from user_view where id = NEW.id; - END IF; - - return null; -end $$; - -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set hot_rank = pav.hot_rank - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id; - - -- Force the hot rank as zero on week-older posts - update post_aggregates_fast as paf - set hot_rank = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '1 week'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; +CREATE OR REPLACE FUNCTION refresh_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to owner changes + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update post view due to community changes + DELETE FROM post_aggregates_fast + WHERE community_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + community_id = NEW.id; + -- TODO make sure this shows up in the users page ? + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION refresh_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id; + -- Refresh post_fast, cause of user info changes + DELETE FROM post_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + creator_id = NEW.id; + DELETE FROM comment_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + creator_id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id; + -- Force the hot rank as zero on week-older posts + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '1 week'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; diff --git a/migrations/2020-10-07-234221_fix_fast_triggers/up.sql b/migrations/2020-10-07-234221_fix_fast_triggers/up.sql index 39f77447..f94cbf1b 100644 --- a/migrations/2020-10-07-234221_fix_fast_triggers/up.sql +++ b/migrations/2020-10-07-234221_fix_fast_triggers/up.sql @@ -1,132 +1,267 @@ -- This adds on conflict do nothing triggers to all the insert_intos -- Github issue: https://github.com/LemmyNet/lemmy/issues/1179 +CREATE OR REPLACE FUNCTION refresh_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM community_aggregates_fast + WHERE id = OLD.id; + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + -- Update user view due to owner changes + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id + ON CONFLICT (id) + DO NOTHING; + -- Update post view due to community changes + DELETE FROM post_aggregates_fast + WHERE community_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + community_id = NEW.id + ON CONFLICT (id) + DO NOTHING; + -- TODO make sure this shows up in the users page ? + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates_fast + SELECT + * + FROM + community_aggregates_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; -create or replace function refresh_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from community_aggregates_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from community_aggregates_fast where id = OLD.id; - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id on conflict (id) do nothing; +CREATE OR REPLACE FUNCTION refresh_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM user_fast + WHERE id = OLD.id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + -- Refresh post_fast, cause of user info changes + DELETE FROM post_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + creator_id = NEW.id + ON CONFLICT (id) + DO NOTHING; + DELETE FROM comment_aggregates_fast + WHERE creator_id = NEW.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + creator_id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.id; + END IF; + RETURN NULL; +END +$$; - -- Update user view due to owner changes - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id on conflict (id) do nothing; - - -- Update post view due to community changes - delete from post_aggregates_fast where community_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where community_id = NEW.id on conflict (id) do nothing; +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id + ON CONFLICT (id) + DO NOTHING; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; - -- TODO make sure this shows up in the users page ? - ELSIF (TG_OP = 'INSERT') THEN - insert into community_aggregates_fast select * from community_aggregates_view where id = NEW.id; - END IF; +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id + ON CONFLICT (id) + DO NOTHING; + -- Force the hot rank as zero on week-older posts + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '1 week'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; - return null; -end $$; - -create or replace function refresh_user() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from user_fast where id = OLD.id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from user_fast where id = OLD.id; - insert into user_fast select * from user_view where id = NEW.id on conflict(id) do nothing; - - -- Refresh post_fast, cause of user info changes - delete from post_aggregates_fast where creator_id = NEW.id; - insert into post_aggregates_fast select * from post_aggregates_view where creator_id = NEW.id on conflict (id) do nothing; - - delete from comment_aggregates_fast where creator_id = NEW.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where creator_id = NEW.id on conflict (id) do nothing; - - ELSIF (TG_OP = 'INSERT') THEN - insert into user_fast select * from user_view where id = NEW.id; - END IF; - - return null; -end $$; - -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id on conflict (id) do nothing; - - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id on conflict (id) do nothing; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set hot_rank = pav.hot_rank - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id on conflict (id) do nothing; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id on conflict (id) do nothing; - - -- Force the hot rank as zero on week-older posts - update post_aggregates_fast as paf - set hot_rank = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '1 week'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; diff --git a/migrations/2020-10-10-035723_fix_fast_triggers_2/down.sql b/migrations/2020-10-10-035723_fix_fast_triggers_2/down.sql index d05418f5..291913cb 100644 --- a/migrations/2020-10-10-035723_fix_fast_triggers_2/down.sql +++ b/migrations/2020-10-10-035723_fix_fast_triggers_2/down.sql @@ -1,79 +1,151 @@ -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id + ON CONFLICT (id) + DO NOTHING; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id on conflict (id) do nothing; +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id + ON CONFLICT (id) + DO NOTHING; + -- Force the hot rank as zero on week-older posts + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '1 week'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id on conflict (id) do nothing; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set hot_rank = pav.hot_rank - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id on conflict (id) do nothing; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id on conflict (id) do nothing; - - -- Force the hot rank as zero on week-older posts - update post_aggregates_fast as paf - set hot_rank = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '1 week'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; diff --git a/migrations/2020-10-10-035723_fix_fast_triggers_2/up.sql b/migrations/2020-10-10-035723_fix_fast_triggers_2/up.sql index 64a5dccb..44934412 100644 --- a/migrations/2020-10-10-035723_fix_fast_triggers_2/up.sql +++ b/migrations/2020-10-10-035723_fix_fast_triggers_2/up.sql @@ -1,97 +1,175 @@ -- Forgot to add hot rank active to these two triggers +CREATE OR REPLACE FUNCTION refresh_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts - 1 + WHERE + id = OLD.community_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM post_aggregates_fast + WHERE id = OLD.id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.id; + -- Update that users number of posts, post score + DELETE FROM user_fast + WHERE id = NEW.creator_id; + INSERT INTO user_fast + SELECT + * + FROM + user_view + WHERE + id = NEW.creator_id + ON CONFLICT (id) + DO NOTHING; + -- Update community number of posts + UPDATE + community_aggregates_fast + SET + number_of_posts = number_of_posts + 1 + WHERE + id = NEW.community_id; + -- Update the hot rank on the post table + -- TODO this might not correctly update it, using a 1 week interval + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank, + hot_rank_active = pav.hot_rank_active + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + END IF; + RETURN NULL; +END +$$; -create or replace function refresh_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from post_aggregates_fast where id = OLD.id; +CREATE OR REPLACE FUNCTION refresh_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments - 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + DELETE FROM comment_aggregates_fast + WHERE id = OLD.id; + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id + ON CONFLICT (id) + DO NOTHING; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates_fast + SELECT + * + FROM + comment_aggregates_view + WHERE + id = NEW.id; + -- Update user view due to comment count + UPDATE + user_fast + SET + number_of_comments = number_of_comments + 1 + WHERE + id = NEW.creator_id; + -- Update post view due to comment count, new comment activity time, but only on new posts + -- TODO this could be done more efficiently + DELETE FROM post_aggregates_fast + WHERE id = NEW.post_id; + INSERT INTO post_aggregates_fast + SELECT + * + FROM + post_aggregates_view + WHERE + id = NEW.post_id + ON CONFLICT (id) + DO NOTHING; + -- Update the comment hot_ranks as of last week + UPDATE + comment_aggregates_fast AS caf + SET + hot_rank = cav.hot_rank, + hot_rank_active = cav.hot_rank_active + FROM + comment_aggregates_view AS cav + WHERE + caf.id = cav.id + AND (cav.published > ('now'::timestamp - '1 week'::interval)); + -- Update the post ranks + UPDATE + post_aggregates_fast AS paf + SET + hot_rank = pav.hot_rank, + hot_rank_active = pav.hot_rank_active + FROM + post_aggregates_view AS pav + WHERE + paf.id = pav.id + AND (pav.published > ('now'::timestamp - '1 week'::interval)); + -- Force the hot rank active as zero on 2 day-older posts (necro-bump) + UPDATE + post_aggregates_fast AS paf + SET + hot_rank_active = 0 + WHERE + paf.id = NEW.post_id + AND (paf.published < ('now'::timestamp - '2 days'::interval)); + -- Update community number of comments + UPDATE + community_aggregates_fast AS caf + SET + number_of_comments = number_of_comments + 1 + FROM + post AS p + WHERE + caf.id = p.community_id + AND p.id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts - 1 where id = OLD.community_id; - ELSIF (TG_OP = 'UPDATE') THEN - delete from post_aggregates_fast where id = OLD.id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id on conflict (id) do nothing; - ELSIF (TG_OP = 'INSERT') THEN - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.id; - - -- Update that users number of posts, post score - delete from user_fast where id = NEW.creator_id; - insert into user_fast select * from user_view where id = NEW.creator_id on conflict (id) do nothing; - - -- Update community number of posts - update community_aggregates_fast set number_of_posts = number_of_posts + 1 where id = NEW.community_id; - - -- Update the hot rank on the post table - -- TODO this might not correctly update it, using a 1 week interval - update post_aggregates_fast as paf - set - hot_rank = pav.hot_rank, - hot_rank_active = pav.hot_rank_active - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - END IF; - - return null; -end $$; - -create or replace function refresh_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - delete from comment_aggregates_fast where id = OLD.id; - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments - 1 - from post as p - where caf.id = p.community_id and p.id = OLD.post_id; - - ELSIF (TG_OP = 'UPDATE') THEN - delete from comment_aggregates_fast where id = OLD.id; - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id on conflict (id) do nothing; - ELSIF (TG_OP = 'INSERT') THEN - insert into comment_aggregates_fast select * from comment_aggregates_view where id = NEW.id; - - -- Update user view due to comment count - update user_fast - set number_of_comments = number_of_comments + 1 - where id = NEW.creator_id; - - -- Update post view due to comment count, new comment activity time, but only on new posts - -- TODO this could be done more efficiently - delete from post_aggregates_fast where id = NEW.post_id; - insert into post_aggregates_fast select * from post_aggregates_view where id = NEW.post_id on conflict (id) do nothing; - - -- Update the comment hot_ranks as of last week - update comment_aggregates_fast as caf - set - hot_rank = cav.hot_rank, - hot_rank_active = cav.hot_rank_active - from comment_aggregates_view as cav - where caf.id = cav.id and (cav.published > ('now'::timestamp - '1 week'::interval)); - - -- Update the post ranks - update post_aggregates_fast as paf - set - hot_rank = pav.hot_rank, - hot_rank_active = pav.hot_rank_active - from post_aggregates_view as pav - where paf.id = pav.id and (pav.published > ('now'::timestamp - '1 week'::interval)); - - -- Force the hot rank active as zero on 2 day-older posts (necro-bump) - update post_aggregates_fast as paf - set hot_rank_active = 0 - where paf.id = NEW.post_id and (paf.published < ('now'::timestamp - '2 days'::interval)); - - -- Update community number of comments - update community_aggregates_fast as caf - set number_of_comments = number_of_comments + 1 - from post as p - where caf.id = p.community_id and p.id = NEW.post_id; - - END IF; - - return null; -end $$; diff --git a/migrations/2020-10-13-212240_create_report_tables/down.sql b/migrations/2020-10-13-212240_create_report_tables/down.sql index e1c39faa..9dfdbd48 100644 --- a/migrations/2020-10-13-212240_create_report_tables/down.sql +++ b/migrations/2020-10-13-212240_create_report_tables/down.sql @@ -1,4 +1,8 @@ -drop view comment_report_view; -drop view post_report_view; -drop table comment_report; -drop table post_report; +DROP VIEW comment_report_view; + +DROP VIEW post_report_view; + +DROP TABLE comment_report; + +DROP TABLE post_report; + diff --git a/migrations/2020-10-13-212240_create_report_tables/up.sql b/migrations/2020-10-13-212240_create_report_tables/up.sql index e9dce1ad..9aafa3a7 100644 --- a/migrations/2020-10-13-212240_create_report_tables/up.sql +++ b/migrations/2020-10-13-212240_create_report_tables/up.sql @@ -1,89 +1,94 @@ -create table comment_report ( - id serial primary key, - creator_id int references user_ on update cascade on delete cascade not null, -- user reporting comment - comment_id int references comment on update cascade on delete cascade not null, -- comment being reported - original_comment_text text not null, - reason text not null, - resolved bool not null default false, - resolver_id int references user_ on update cascade on delete cascade, -- user resolving report - published timestamp not null default now(), - updated timestamp null, - unique(comment_id, creator_id) -- users should only be able to report a comment once +CREATE TABLE comment_report ( + id serial PRIMARY KEY, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- user reporting comment + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- comment being reported + original_comment_text text NOT NULL, + reason text NOT NULL, + resolved bool NOT NULL DEFAULT FALSE, + resolver_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE, -- user resolving report + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL, + UNIQUE (comment_id, creator_id) -- users should only be able to report a comment once ); -create table post_report ( - id serial primary key, - creator_id int references user_ on update cascade on delete cascade not null, -- user reporting post - post_id int references post on update cascade on delete cascade not null, -- post being reported - original_post_name varchar(100) not null, - original_post_url text, - original_post_body text, - reason text not null, - resolved bool not null default false, - resolver_id int references user_ on update cascade on delete cascade, -- user resolving report - published timestamp not null default now(), - updated timestamp null, - unique(post_id, creator_id) -- users should only be able to report a post once +CREATE TABLE post_report ( + id serial PRIMARY KEY, + creator_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- user reporting post + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- post being reported + original_post_name varchar(100) NOT NULL, + original_post_url text, + original_post_body text, + reason text NOT NULL, + resolved bool NOT NULL DEFAULT FALSE, + resolver_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE, -- user resolving report + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL, + UNIQUE (post_id, creator_id) -- users should only be able to report a post once ); -create or replace view comment_report_view as -select cr.*, -c.post_id, -c.content as current_comment_text, -p.community_id, --- report creator details -f.actor_id as creator_actor_id, -f.name as creator_name, -f.preferred_username as creator_preferred_username, -f.avatar as creator_avatar, -f.local as creator_local, --- comment creator details -u.id as comment_creator_id, -u.actor_id as comment_creator_actor_id, -u.name as comment_creator_name, -u.preferred_username as comment_creator_preferred_username, -u.avatar as comment_creator_avatar, -u.local as comment_creator_local, --- resolver details -r.actor_id as resolver_actor_id, -r.name as resolver_name, -r.preferred_username as resolver_preferred_username, -r.avatar as resolver_avatar, -r.local as resolver_local -from comment_report cr -left join comment c on c.id = cr.comment_id -left join post p on p.id = c.post_id -left join user_ u on u.id = c.creator_id -left join user_ f on f.id = cr.creator_id -left join user_ r on r.id = cr.resolver_id; +CREATE OR REPLACE VIEW comment_report_view AS +SELECT + cr.*, + c.post_id, + c.content AS current_comment_text, + p.community_id, + -- report creator details + f.actor_id AS creator_actor_id, + f.name AS creator_name, + f.preferred_username AS creator_preferred_username, + f.avatar AS creator_avatar, + f.local AS creator_local, + -- comment creator details + u.id AS comment_creator_id, + u.actor_id AS comment_creator_actor_id, + u.name AS comment_creator_name, + u.preferred_username AS comment_creator_preferred_username, + u.avatar AS comment_creator_avatar, + u.local AS comment_creator_local, + -- resolver details + r.actor_id AS resolver_actor_id, + r.name AS resolver_name, + r.preferred_username AS resolver_preferred_username, + r.avatar AS resolver_avatar, + r.local AS resolver_local +FROM + comment_report cr + LEFT JOIN comment c ON c.id = cr.comment_id + LEFT JOIN post p ON p.id = c.post_id + LEFT JOIN user_ u ON u.id = c.creator_id + LEFT JOIN user_ f ON f.id = cr.creator_id + LEFT JOIN user_ r ON r.id = cr.resolver_id; + +CREATE OR REPLACE VIEW post_report_view AS +SELECT + pr.*, + p.name AS current_post_name, + p.url AS current_post_url, + p.body AS current_post_body, + p.community_id, + -- report creator details + f.actor_id AS creator_actor_id, + f.name AS creator_name, + f.preferred_username AS creator_preferred_username, + f.avatar AS creator_avatar, + f.local AS creator_local, + -- post creator details + u.id AS post_creator_id, + u.actor_id AS post_creator_actor_id, + u.name AS post_creator_name, + u.preferred_username AS post_creator_preferred_username, + u.avatar AS post_creator_avatar, + u.local AS post_creator_local, + -- resolver details + r.actor_id AS resolver_actor_id, + r.name AS resolver_name, + r.preferred_username AS resolver_preferred_username, + r.avatar AS resolver_avatar, + r.local AS resolver_local +FROM + post_report pr + LEFT JOIN post p ON p.id = pr.post_id + LEFT JOIN user_ u ON u.id = p.creator_id + LEFT JOIN user_ f ON f.id = pr.creator_id + LEFT JOIN user_ r ON r.id = pr.resolver_id; -create or replace view post_report_view as -select pr.*, -p.name as current_post_name, -p.url as current_post_url, -p.body as current_post_body, -p.community_id, --- report creator details -f.actor_id as creator_actor_id, -f.name as creator_name, -f.preferred_username as creator_preferred_username, -f.avatar as creator_avatar, -f.local as creator_local, --- post creator details -u.id as post_creator_id, -u.actor_id as post_creator_actor_id, -u.name as post_creator_name, -u.preferred_username as post_creator_preferred_username, -u.avatar as post_creator_avatar, -u.local as post_creator_local, --- resolver details -r.actor_id as resolver_actor_id, -r.name as resolver_name, -r.preferred_username as resolver_preferred_username, -r.avatar as resolver_avatar, -r.local as resolver_local -from post_report pr -left join post p on p.id = pr.post_id -left join user_ u on u.id = p.creator_id -left join user_ f on f.id = pr.creator_id -left join user_ r on r.id = pr.resolver_id; diff --git a/migrations/2020-10-23-115011_activity_ap_id_column/down.sql b/migrations/2020-10-23-115011_activity_ap_id_column/down.sql index 7978df72..5abef5a7 100644 --- a/migrations/2020-10-23-115011_activity_ap_id_column/down.sql +++ b/migrations/2020-10-23-115011_activity_ap_id_column/down.sql @@ -1 +1,3 @@ -ALTER TABLE activity DROP COLUMN ap_id; \ No newline at end of file +ALTER TABLE activity + DROP COLUMN ap_id; + diff --git a/migrations/2020-10-23-115011_activity_ap_id_column/up.sql b/migrations/2020-10-23-115011_activity_ap_id_column/up.sql index ab22a4c4..d0df8814 100644 --- a/migrations/2020-10-23-115011_activity_ap_id_column/up.sql +++ b/migrations/2020-10-23-115011_activity_ap_id_column/up.sql @@ -1 +1,3 @@ -ALTER TABLE activity ADD COLUMN ap_id TEXT; \ No newline at end of file +ALTER TABLE activity + ADD COLUMN ap_id TEXT; + diff --git a/migrations/2020-11-05-152724_activity_remove_user_id/down.sql b/migrations/2020-11-05-152724_activity_remove_user_id/down.sql index bb093f1b..580c93e0 100644 --- a/migrations/2020-11-05-152724_activity_remove_user_id/down.sql +++ b/migrations/2020-11-05-152724_activity_remove_user_id/down.sql @@ -1,2 +1,6 @@ -ALTER TABLE activity ADD COLUMN user_id INTEGER; -ALTER TABLE activity DROP COLUMN sensitive; \ No newline at end of file +ALTER TABLE activity + ADD COLUMN user_id INTEGER; + +ALTER TABLE activity + DROP COLUMN sensitive; + diff --git a/migrations/2020-11-05-152724_activity_remove_user_id/up.sql b/migrations/2020-11-05-152724_activity_remove_user_id/up.sql index 22a1a2fa..66b33dd8 100644 --- a/migrations/2020-11-05-152724_activity_remove_user_id/up.sql +++ b/migrations/2020-11-05-152724_activity_remove_user_id/up.sql @@ -1,2 +1,6 @@ -ALTER TABLE activity DROP COLUMN user_id; -ALTER TABLE activity ADD COLUMN sensitive BOOLEAN DEFAULT TRUE; \ No newline at end of file +ALTER TABLE activity + DROP COLUMN user_id; + +ALTER TABLE activity + ADD COLUMN sensitive BOOLEAN DEFAULT TRUE; + diff --git a/migrations/2020-11-10-150835_community_follower_pending/down.sql b/migrations/2020-11-10-150835_community_follower_pending/down.sql index 72cbeaa3..f61482f9 100644 --- a/migrations/2020-11-10-150835_community_follower_pending/down.sql +++ b/migrations/2020-11-10-150835_community_follower_pending/down.sql @@ -1 +1,3 @@ -ALTER TABLE community_follower DROP COLUMN pending; \ No newline at end of file +ALTER TABLE community_follower + DROP COLUMN pending; + diff --git a/migrations/2020-11-10-150835_community_follower_pending/up.sql b/migrations/2020-11-10-150835_community_follower_pending/up.sql index 599bed62..163dc052 100644 --- a/migrations/2020-11-10-150835_community_follower_pending/up.sql +++ b/migrations/2020-11-10-150835_community_follower_pending/up.sql @@ -1 +1,3 @@ -ALTER TABLE community_follower ADD COLUMN pending BOOLEAN DEFAULT FALSE; \ No newline at end of file +ALTER TABLE community_follower + ADD COLUMN pending BOOLEAN DEFAULT FALSE; + diff --git a/migrations/2020-11-26-134531_delete_user/down.sql b/migrations/2020-11-26-134531_delete_user/down.sql index 09b05878..51a9ef6b 100644 --- a/migrations/2020-11-26-134531_delete_user/down.sql +++ b/migrations/2020-11-26-134531_delete_user/down.sql @@ -1 +1,3 @@ -ALTER TABLE user_ DROP COLUMN deleted; +ALTER TABLE user_ + DROP COLUMN deleted; + diff --git a/migrations/2020-11-26-134531_delete_user/up.sql b/migrations/2020-11-26-134531_delete_user/up.sql index 1d752c57..7fc226f6 100644 --- a/migrations/2020-11-26-134531_delete_user/up.sql +++ b/migrations/2020-11-26-134531_delete_user/up.sql @@ -1 +1,3 @@ -ALTER TABLE user_ ADD COLUMN deleted BOOLEAN DEFAULT FALSE NOT NULL; +ALTER TABLE user_ + ADD COLUMN deleted BOOLEAN DEFAULT FALSE NOT NULL; + diff --git a/migrations/2020-12-02-152437_create_site_aggregates/down.sql b/migrations/2020-12-02-152437_create_site_aggregates/down.sql index 914bdb8d..6535f0da 100644 --- a/migrations/2020-12-02-152437_create_site_aggregates/down.sql +++ b/migrations/2020-12-02-152437_create_site_aggregates/down.sql @@ -1,21 +1,23 @@ -- Site aggregates -drop table site_aggregates; -drop trigger site_aggregates_site on site; -drop trigger site_aggregates_user_insert on user_; -drop trigger site_aggregates_user_delete on user_; -drop trigger site_aggregates_post_insert on post; -drop trigger site_aggregates_post_delete on post; -drop trigger site_aggregates_comment_insert on comment; -drop trigger site_aggregates_comment_delete on comment; -drop trigger site_aggregates_community_insert on community; -drop trigger site_aggregates_community_delete on community; -drop function - site_aggregates_site, - site_aggregates_user_insert, - site_aggregates_user_delete, - site_aggregates_post_insert, - site_aggregates_post_delete, - site_aggregates_comment_insert, - site_aggregates_comment_delete, - site_aggregates_community_insert, - site_aggregates_community_delete; +DROP TABLE site_aggregates; + +DROP TRIGGER site_aggregates_site ON site; + +DROP TRIGGER site_aggregates_user_insert ON user_; + +DROP TRIGGER site_aggregates_user_delete ON user_; + +DROP TRIGGER site_aggregates_post_insert ON post; + +DROP TRIGGER site_aggregates_post_delete ON post; + +DROP TRIGGER site_aggregates_comment_insert ON comment; + +DROP TRIGGER site_aggregates_comment_delete ON comment; + +DROP TRIGGER site_aggregates_community_insert ON community; + +DROP TRIGGER site_aggregates_community_delete ON community; + +DROP FUNCTION site_aggregates_site, site_aggregates_user_insert, site_aggregates_user_delete, site_aggregates_post_insert, site_aggregates_post_delete, site_aggregates_comment_insert, site_aggregates_comment_delete, site_aggregates_community_insert, site_aggregates_community_delete; + diff --git a/migrations/2020-12-02-152437_create_site_aggregates/up.sql b/migrations/2020-12-02-152437_create_site_aggregates/up.sql index 679543d1..79b5a9f8 100644 --- a/migrations/2020-12-02-152437_create_site_aggregates/up.sql +++ b/migrations/2020-12-02-152437_create_site_aggregates/up.sql @@ -1,169 +1,240 @@ -- Add site aggregates -create table site_aggregates ( - id serial primary key, - site_id int references site on update cascade on delete cascade not null, - users bigint not null default 1, - posts bigint not null default 0, - comments bigint not null default 0, - communities bigint not null default 0 +CREATE TABLE site_aggregates ( + id serial PRIMARY KEY, + site_id int REFERENCES site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + users bigint NOT NULL DEFAULT 1, + posts bigint NOT NULL DEFAULT 0, + comments bigint NOT NULL DEFAULT 0, + communities bigint NOT NULL DEFAULT 0 ); -insert into site_aggregates (site_id, users, posts, comments, communities) - select id as site_id, - ( select coalesce(count(*), 0) from user_ where local = true) as users, - ( select coalesce(count(*), 0) from post where local = true) as posts, - ( select coalesce(count(*), 0) from comment where local = true) as comments, - ( select coalesce(count(*), 0) from community where local = true) as communities - from site; +INSERT INTO site_aggregates (site_id, users, posts, comments, communities) +SELECT + id AS site_id, + ( + SELECT + coalesce(count(*), 0) + FROM + user_ + WHERE + local = TRUE) AS users, + ( + SELECT + coalesce(count(*), 0) + FROM + post + WHERE + local = TRUE) AS posts, + ( + SELECT + coalesce(count(*), 0) + FROM + comment + WHERE + local = TRUE) AS comments, + ( + SELECT + coalesce(count(*), 0) + FROM + community + WHERE + local = TRUE) AS communities +FROM + site; -- initial site add -create function site_aggregates_site() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into site_aggregates (site_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from site_aggregates where site_id = OLD.id; - END IF; - return null; -end $$; - -create trigger site_aggregates_site -after insert or delete on site -for each row -execute procedure site_aggregates_site(); +CREATE FUNCTION site_aggregates_site () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO site_aggregates (site_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM site_aggregates + WHERE site_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER site_aggregates_site + AFTER INSERT OR DELETE ON site + FOR EACH ROW + EXECUTE PROCEDURE site_aggregates_site (); -- Add site aggregate triggers -- user -create function site_aggregates_user_insert() -returns trigger language plpgsql -as $$ -begin - update site_aggregates - set users = users + 1; - return null; -end $$; - -create function site_aggregates_user_delete() -returns trigger language plpgsql -as $$ -begin - -- Join to site since the creator might not be there anymore - update site_aggregates sa - set users = users - 1 - from site s - where sa.site_id = s.id; - return null; -end $$; - -create trigger site_aggregates_user_insert -after insert on user_ -for each row -when (NEW.local = true) -execute procedure site_aggregates_user_insert(); - -create trigger site_aggregates_user_delete -after delete on user_ -for each row -when (OLD.local = true) -execute procedure site_aggregates_user_delete(); +CREATE FUNCTION site_aggregates_user_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + users = users + 1; + RETURN NULL; +END +$$; + +CREATE FUNCTION site_aggregates_user_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- Join to site since the creator might not be there anymore + UPDATE + site_aggregates sa + SET + users = users - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE TRIGGER site_aggregates_user_insert + AFTER INSERT ON user_ + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_user_insert (); + +CREATE TRIGGER site_aggregates_user_delete + AFTER DELETE ON user_ + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_user_delete (); -- post -create function site_aggregates_post_insert() -returns trigger language plpgsql -as $$ -begin - update site_aggregates - set posts = posts + 1; - return null; -end $$; - -create function site_aggregates_post_delete() -returns trigger language plpgsql -as $$ -begin - update site_aggregates sa - set posts = posts - 1 - from site s - where sa.site_id = s.id; - return null; -end $$; - -create trigger site_aggregates_post_insert -after insert on post -for each row -when (NEW.local = true) -execute procedure site_aggregates_post_insert(); - -create trigger site_aggregates_post_delete -after delete on post -for each row -when (OLD.local = true) -execute procedure site_aggregates_post_delete(); +CREATE FUNCTION site_aggregates_post_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + posts = posts + 1; + RETURN NULL; +END +$$; + +CREATE FUNCTION site_aggregates_post_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + posts = posts - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE TRIGGER site_aggregates_post_insert + AFTER INSERT ON post + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_insert (); + +CREATE TRIGGER site_aggregates_post_delete + AFTER DELETE ON post + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_delete (); -- comment -create function site_aggregates_comment_insert() -returns trigger language plpgsql -as $$ -begin - update site_aggregates - set comments = comments + 1; - return null; -end $$; - -create function site_aggregates_comment_delete() -returns trigger language plpgsql -as $$ -begin - update site_aggregates sa - set comments = comments - 1 - from site s - where sa.site_id = s.id; - return null; -end $$; - -create trigger site_aggregates_comment_insert -after insert on comment -for each row -when (NEW.local = true) -execute procedure site_aggregates_comment_insert(); - -create trigger site_aggregates_comment_delete -after delete on comment -for each row -when (OLD.local = true) -execute procedure site_aggregates_comment_delete(); +CREATE FUNCTION site_aggregates_comment_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + comments = comments + 1; + RETURN NULL; +END +$$; + +CREATE FUNCTION site_aggregates_comment_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + comments = comments - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE TRIGGER site_aggregates_comment_insert + AFTER INSERT ON comment + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_insert (); + +CREATE TRIGGER site_aggregates_comment_delete + AFTER DELETE ON comment + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_delete (); -- community -create function site_aggregates_community_insert() -returns trigger language plpgsql -as $$ -begin - update site_aggregates - set communities = communities + 1; - return null; -end $$; - -create function site_aggregates_community_delete() -returns trigger language plpgsql -as $$ -begin - update site_aggregates sa - set communities = communities - 1 - from site s - where sa.site_id = s.id; - return null; -end $$; - -create trigger site_aggregates_community_insert -after insert on community -for each row -when (NEW.local = true) -execute procedure site_aggregates_community_insert(); - -create trigger site_aggregates_community_delete -after delete on community -for each row -when (OLD.local = true) -execute procedure site_aggregates_community_delete(); +CREATE FUNCTION site_aggregates_community_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + communities = communities + 1; + RETURN NULL; +END +$$; + +CREATE FUNCTION site_aggregates_community_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + communities = communities - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE TRIGGER site_aggregates_community_insert + AFTER INSERT ON community + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_insert (); + +CREATE TRIGGER site_aggregates_community_delete + AFTER DELETE ON community + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_delete (); + diff --git a/migrations/2020-12-03-035643_create_user_aggregates/down.sql b/migrations/2020-12-03-035643_create_user_aggregates/down.sql index a7b5e473..756919d9 100644 --- a/migrations/2020-12-03-035643_create_user_aggregates/down.sql +++ b/migrations/2020-12-03-035643_create_user_aggregates/down.sql @@ -1,13 +1,15 @@ -- User aggregates -drop table user_aggregates; -drop trigger user_aggregates_user on user_; -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; +DROP TABLE user_aggregates; + +DROP TRIGGER user_aggregates_user ON user_; + +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; + diff --git a/migrations/2020-12-03-035643_create_user_aggregates/up.sql b/migrations/2020-12-03-035643_create_user_aggregates/up.sql index 7b4c83af..79218b90 100644 --- a/migrations/2020-12-03-035643_create_user_aggregates/up.sql +++ b/migrations/2020-12-03-035643_create_user_aggregates/up.sql @@ -1,178 +1,236 @@ -- Add user aggregates -create table user_aggregates ( - id serial primary key, - user_id int references user_ on update cascade on delete cascade not null, - post_count bigint not null default 0, - post_score bigint not null default 0, - comment_count bigint not null default 0, - comment_score bigint not null default 0, - unique (user_id) +CREATE TABLE user_aggregates ( + id serial PRIMARY KEY, + user_id int REFERENCES user_ ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_count bigint NOT NULL DEFAULT 0, + post_score bigint NOT NULL DEFAULT 0, + comment_count bigint NOT NULL DEFAULT 0, + comment_score bigint NOT NULL DEFAULT 0, + UNIQUE (user_id) ); -insert into user_aggregates (user_id, post_count, post_score, comment_count, comment_score) - select u.id, - coalesce(pd.posts, 0), - coalesce(pd.score, 0), - coalesce(cd.comments, 0), - coalesce(cd.score, 0) - from user_ u - left join ( - select p.creator_id, - count(distinct p.id) as posts, - sum(pl.score) as score - from post p - left join post_like pl on p.id = pl.post_id - group by p.creator_id - ) pd on u.id = pd.creator_id - left join ( - select c.creator_id, - count(distinct c.id) as comments, - sum(cl.score) as score - from comment c - left join comment_like cl on c.id = cl.comment_id - group by c.creator_id - ) cd on u.id = cd.creator_id; - +INSERT INTO user_aggregates (user_id, post_count, post_score, comment_count, comment_score) +SELECT + u.id, + coalesce(pd.posts, 0), + coalesce(pd.score, 0), + coalesce(cd.comments, 0), + coalesce(cd.score, 0) +FROM + user_ u + LEFT JOIN ( + SELECT + p.creator_id, + count(DISTINCT p.id) AS posts, + sum(pl.score) AS score + FROM + post p + LEFT JOIN post_like pl ON p.id = pl.post_id + GROUP BY + p.creator_id) pd ON u.id = pd.creator_id + LEFT JOIN ( + SELECT + c.creator_id, + count(DISTINCT c.id) AS comments, + sum(cl.score) AS score + FROM + comment c + LEFT JOIN comment_like cl ON c.id = cl.comment_id + GROUP BY + c.creator_id) cd ON u.id = cd.creator_id; -- Add user aggregate triggers - -- initial user add -create function user_aggregates_user() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into user_aggregates (user_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from user_aggregates where user_id = OLD.id; - END IF; - return null; -end $$; - -create trigger user_aggregates_user -after insert or delete on user_ -for each row -execute procedure user_aggregates_user(); +CREATE FUNCTION user_aggregates_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO user_aggregates (user_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM user_aggregates + WHERE user_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_user + AFTER INSERT OR DELETE ON user_ + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_user (); -- post count -create function user_aggregates_post_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update user_aggregates - set post_count = post_count + 1 where user_id = NEW.creator_id; - - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates - set post_count = post_count - 1 where user_id = OLD.creator_id; - - -- If the post gets deleted, the score calculation trigger won't fire, - -- so you need to re-calculate - update user_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 user_ 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.user_id = OLD.creator_id; - - END IF; - return null; -end $$; - -create trigger user_aggregates_post_count -after insert or delete on post -for each row -execute procedure user_aggregates_post_count(); +CREATE FUNCTION user_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + user_aggregates + SET + post_count = post_count + 1 + WHERE + user_id = NEW.creator_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates + SET + post_count = post_count - 1 + WHERE + user_id = OLD.creator_id; + -- If the post gets deleted, the score calculation trigger won't fire, + -- so you need to re-calculate + UPDATE + user_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 + user_ 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.user_id = OLD.creator_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_post_count + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_post_count (); -- post score -create function user_aggregates_post_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - -- Need to get the post creator, not the voter - update user_aggregates ua - set post_score = post_score + NEW.score - from post p - where ua.user_id = p.creator_id and p.id = NEW.post_id; - - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates ua - set post_score = post_score - OLD.score - from post p - where ua.user_id = p.creator_id and p.id = OLD.post_id; - END IF; - return null; -end $$; - -create trigger user_aggregates_post_score -after insert or delete on post_like -for each row -execute procedure user_aggregates_post_score(); +CREATE FUNCTION user_aggregates_post_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + -- Need to get the post creator, not the voter + UPDATE + user_aggregates ua + SET + post_score = post_score + NEW.score + FROM + post p + WHERE + ua.user_id = p.creator_id + AND p.id = NEW.post_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates ua + SET + post_score = post_score - OLD.score + FROM + post p + WHERE + ua.user_id = p.creator_id + AND p.id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_post_score + AFTER INSERT OR DELETE ON post_like + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_post_score (); -- comment count -create function user_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update user_aggregates - set comment_count = comment_count + 1 where user_id = NEW.creator_id; - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates - set comment_count = comment_count - 1 where user_id = OLD.creator_id; - - -- If the comment gets deleted, the score calculation trigger won't fire, - -- so you need to re-calculate - update user_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 user_ 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.user_id = OLD.creator_id; - END IF; - return null; -end $$; - -create trigger user_aggregates_comment_count -after insert or delete on comment -for each row -execute procedure user_aggregates_comment_count(); +CREATE FUNCTION user_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + user_aggregates + SET + comment_count = comment_count + 1 + WHERE + user_id = NEW.creator_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates + SET + comment_count = comment_count - 1 + WHERE + user_id = OLD.creator_id; + -- If the comment gets deleted, the score calculation trigger won't fire, + -- so you need to re-calculate + UPDATE + user_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 + user_ 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.user_id = OLD.creator_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_comment_count (); -- comment score -create function user_aggregates_comment_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - -- Need to get the post creator, not the voter - update user_aggregates ua - set comment_score = comment_score + NEW.score - from comment c - where ua.user_id = c.creator_id and c.id = NEW.comment_id; - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates ua - set comment_score = comment_score - OLD.score - from comment c - where ua.user_id = c.creator_id and c.id = OLD.comment_id; - END IF; - return null; -end $$; +CREATE FUNCTION user_aggregates_comment_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + -- Need to get the post creator, not the voter + UPDATE + user_aggregates ua + SET + comment_score = comment_score + NEW.score + FROM + comment c + WHERE + ua.user_id = c.creator_id + AND c.id = NEW.comment_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates ua + SET + comment_score = comment_score - OLD.score + FROM + comment c + WHERE + ua.user_id = c.creator_id + AND c.id = OLD.comment_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_comment_score + AFTER INSERT OR DELETE ON comment_like + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_comment_score (); -create trigger user_aggregates_comment_score -after insert or delete on comment_like -for each row -execute procedure user_aggregates_comment_score(); diff --git a/migrations/2020-12-04-183345_create_community_aggregates/down.sql b/migrations/2020-12-04-183345_create_community_aggregates/down.sql index fc0ffd21..6a694e50 100644 --- a/migrations/2020-12-04-183345_create_community_aggregates/down.sql +++ b/migrations/2020-12-04-183345_create_community_aggregates/down.sql @@ -1,11 +1,13 @@ -- community aggregates -drop table community_aggregates; -drop trigger community_aggregates_community on community; -drop trigger community_aggregates_post_count on post; -drop trigger community_aggregates_comment_count on comment; -drop trigger community_aggregates_subscriber_count on community_follower; -drop function - community_aggregates_community, - community_aggregates_post_count, - community_aggregates_comment_count, - community_aggregates_subscriber_count; +DROP TABLE community_aggregates; + +DROP TRIGGER community_aggregates_community ON community; + +DROP TRIGGER community_aggregates_post_count ON post; + +DROP TRIGGER community_aggregates_comment_count ON comment; + +DROP TRIGGER community_aggregates_subscriber_count ON community_follower; + +DROP FUNCTION community_aggregates_community, community_aggregates_post_count, community_aggregates_comment_count, community_aggregates_subscriber_count; + diff --git a/migrations/2020-12-04-183345_create_community_aggregates/up.sql b/migrations/2020-12-04-183345_create_community_aggregates/up.sql index 129b58c0..2770d3d8 100644 --- a/migrations/2020-12-04-183345_create_community_aggregates/up.sql +++ b/migrations/2020-12-04-183345_create_community_aggregates/up.sql @@ -1,138 +1,181 @@ -- Add community aggregates -create table community_aggregates ( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - subscribers bigint not null default 0, - posts bigint not null default 0, - comments bigint not null default 0, - published timestamp not null default now(), - unique (community_id) +CREATE TABLE community_aggregates ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + subscribers bigint NOT NULL DEFAULT 0, + posts bigint NOT NULL DEFAULT 0, + comments bigint NOT NULL DEFAULT 0, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (community_id) ); -insert into community_aggregates (community_id, subscribers, posts, comments, published) - select +INSERT INTO community_aggregates (community_id, subscribers, posts, comments, published) +SELECT c.id, - coalesce(cf.subs, 0) as subscribers, - coalesce(cd.posts, 0) as posts, - coalesce(cd.comments, 0) as comments, + coalesce(cf.subs, 0) AS subscribers, + coalesce(cd.posts, 0) AS posts, + coalesce(cd.comments, 0) AS comments, c.published - from community c - left join ( - select - p.community_id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from post p - left join comment ct on p.id = ct.post_id - group by p.community_id - ) cd on cd.community_id = c.id - left join ( - select - community_follower.community_id, - count(*) as subs - from community_follower - group by community_follower.community_id - ) cf on cf.community_id = c.id; +FROM + community c + LEFT JOIN ( + SELECT + p.community_id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + post p + LEFT JOIN comment ct ON p.id = ct.post_id + GROUP BY + p.community_id) cd ON cd.community_id = c.id + LEFT JOIN ( + SELECT + community_follower.community_id, + count(*) AS subs + FROM + community_follower + GROUP BY + community_follower.community_id) cf ON cf.community_id = c.id; -- Add community aggregate triggers - -- initial community add -create function community_aggregates_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into community_aggregates (community_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from community_aggregates where community_id = OLD.id; - END IF; - return null; -end $$; +CREATE FUNCTION community_aggregates_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates (community_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates + WHERE community_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create trigger community_aggregates_community -after insert or delete on community -for each row -execute procedure community_aggregates_community(); --- post count -create function community_aggregates_post_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update community_aggregates - set posts = posts + 1 where community_id = NEW.community_id; - ELSIF (TG_OP = 'DELETE') THEN - update community_aggregates - set posts = posts - 1 where community_id = OLD.community_id; +CREATE TRIGGER community_aggregates_community + AFTER INSERT OR DELETE ON community + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_community (); - -- Update the counts if the post got deleted - update community_aggregates ca - set posts = coalesce(cd.posts, 0), - comments = coalesce(cd.comments, 0) - from ( - select - c.id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from community c - left join post p on c.id = p.community_id - left join comment ct on p.id = ct.post_id - group by c.id - ) cd - where ca.community_id = OLD.community_id; - END IF; - return null; -end $$; +-- post count +CREATE FUNCTION community_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + community_aggregates + SET + posts = posts + 1 + WHERE + community_id = NEW.community_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates + SET + posts = posts - 1 + WHERE + community_id = OLD.community_id; + -- Update the counts if the post got deleted + UPDATE + community_aggregates ca + SET + posts = coalesce(cd.posts, 0), + comments = coalesce(cd.comments, 0) + FROM ( + SELECT + c.id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + community c + LEFT JOIN post p ON c.id = p.community_id + LEFT JOIN comment ct ON p.id = ct.post_id + GROUP BY + c.id) cd + WHERE + ca.community_id = OLD.community_id; + END IF; + RETURN NULL; +END +$$; -create trigger community_aggregates_post_count -after insert or delete on post -for each row -execute procedure community_aggregates_post_count(); +CREATE TRIGGER community_aggregates_post_count + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_post_count (); -- comment count -create function community_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update community_aggregates ca - set comments = comments + 1 from comment c, post p - where p.id = c.post_id - and p.id = NEW.post_id - and ca.community_id = p.community_id; - ELSIF (TG_OP = 'DELETE') THEN - update community_aggregates ca - set comments = comments - 1 from comment c, post p - where p.id = c.post_id - and p.id = OLD.post_id - and ca.community_id = p.community_id; - - END IF; - return null; -end $$; +CREATE FUNCTION community_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + community_aggregates ca + SET + comments = comments + 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = NEW.post_id + AND ca.community_id = p.community_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates ca + SET + comments = comments - 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = OLD.post_id + AND ca.community_id = p.community_id; + END IF; + RETURN NULL; +END +$$; -create trigger community_aggregates_comment_count -after insert or delete on comment -for each row -execute procedure community_aggregates_comment_count(); +CREATE TRIGGER community_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_comment_count (); -- subscriber count -create function community_aggregates_subscriber_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update community_aggregates - set subscribers = subscribers + 1 where community_id = NEW.community_id; - ELSIF (TG_OP = 'DELETE') THEN - update community_aggregates - set subscribers = subscribers - 1 where community_id = OLD.community_id; - END IF; - return null; -end $$; +CREATE FUNCTION community_aggregates_subscriber_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + community_aggregates + SET + subscribers = subscribers + 1 + WHERE + community_id = NEW.community_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates + SET + subscribers = subscribers - 1 + WHERE + community_id = OLD.community_id; + END IF; + RETURN NULL; +END +$$; -create trigger community_aggregates_subscriber_count -after insert or delete on community_follower -for each row -execute procedure community_aggregates_subscriber_count(); +CREATE TRIGGER community_aggregates_subscriber_count + AFTER INSERT OR DELETE ON community_follower + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_subscriber_count (); diff --git a/migrations/2020-12-10-152350_create_post_aggregates/down.sql b/migrations/2020-12-10-152350_create_post_aggregates/down.sql index 7b4024cd..38bfb998 100644 --- a/migrations/2020-12-10-152350_create_post_aggregates/down.sql +++ b/migrations/2020-12-10-152350_create_post_aggregates/down.sql @@ -1,11 +1,13 @@ -- post aggregates -drop table post_aggregates; -drop trigger post_aggregates_post on post; -drop trigger post_aggregates_comment_count on comment; -drop trigger post_aggregates_score on post_like; -drop trigger post_aggregates_stickied on post; -drop function - post_aggregates_post, - post_aggregates_comment_count, - post_aggregates_score, - post_aggregates_stickied; +DROP TABLE post_aggregates; + +DROP TRIGGER post_aggregates_post ON post; + +DROP TRIGGER post_aggregates_comment_count ON comment; + +DROP TRIGGER post_aggregates_score ON post_like; + +DROP TRIGGER post_aggregates_stickied ON post; + +DROP FUNCTION post_aggregates_post, post_aggregates_comment_count, post_aggregates_score, post_aggregates_stickied; + diff --git a/migrations/2020-12-10-152350_create_post_aggregates/up.sql b/migrations/2020-12-10-152350_create_post_aggregates/up.sql index fcb3a939..7ee817dc 100644 --- a/migrations/2020-12-10-152350_create_post_aggregates/up.sql +++ b/migrations/2020-12-10-152350_create_post_aggregates/up.sql @@ -1,140 +1,187 @@ -- Add post aggregates -create table post_aggregates ( - id serial primary key, - post_id int references post on update cascade on delete cascade not null, - comments bigint not null default 0, - score bigint not null default 0, - upvotes bigint not null default 0, - downvotes bigint not null default 0, - stickied boolean not null default false, - published timestamp not null default now(), - newest_comment_time timestamp not null default now(), - unique (post_id) +CREATE TABLE post_aggregates ( + id serial PRIMARY KEY, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + comments bigint NOT NULL DEFAULT 0, + score bigint NOT NULL DEFAULT 0, + upvotes bigint NOT NULL DEFAULT 0, + downvotes bigint NOT NULL DEFAULT 0, + stickied boolean NOT NULL DEFAULT FALSE, + published timestamp NOT NULL DEFAULT now(), + newest_comment_time timestamp NOT NULL DEFAULT now(), + UNIQUE (post_id) ); -insert into post_aggregates (post_id, comments, score, upvotes, downvotes, stickied, published, newest_comment_time) - select +INSERT INTO post_aggregates (post_id, comments, score, upvotes, downvotes, stickied, published, newest_comment_time) +SELECT p.id, - coalesce(ct.comments, 0::bigint) as comments, - coalesce(pl.score, 0::bigint) as score, - coalesce(pl.upvotes, 0::bigint) as upvotes, - coalesce(pl.downvotes, 0::bigint) as downvotes, + coalesce(ct.comments, 0::bigint) AS comments, + coalesce(pl.score, 0::bigint) AS score, + coalesce(pl.upvotes, 0::bigint) AS upvotes, + coalesce(pl.downvotes, 0::bigint) AS downvotes, p.stickied, p.published, - greatest(ct.recent_comment_time, p.published) as newest_activity_time - from post p - left join ( - select comment.post_id, - count(*) as comments, - max(comment.published) as recent_comment_time - from comment - group by comment.post_id - ) ct on ct.post_id = p.id - left join ( - select post_like.post_id, - sum(post_like.score) as score, - sum(post_like.score) filter (where post_like.score = 1) as upvotes, - -sum(post_like.score) filter (where post_like.score = '-1'::integer) as downvotes - from post_like - group by post_like.post_id - ) pl on pl.post_id = p.id; + greatest (ct.recent_comment_time, p.published) AS newest_activity_time +FROM + post p + LEFT JOIN ( + SELECT + comment.post_id, + count(*) AS comments, + max(comment.published) AS recent_comment_time + FROM + comment + GROUP BY + comment.post_id) ct ON ct.post_id = p.id + LEFT JOIN ( + SELECT + post_like.post_id, + sum(post_like.score) AS score, + sum(post_like.score) FILTER (WHERE post_like.score = 1) AS upvotes, + - sum(post_like.score) FILTER (WHERE post_like.score = '-1'::integer) AS downvotes + FROM + post_like + GROUP BY + post_like.post_id) pl ON pl.post_id = p.id; -- Add community aggregate triggers - -- initial post add -create function post_aggregates_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into post_aggregates (post_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from post_aggregates where post_id = OLD.id; - END IF; - return null; -end $$; +CREATE FUNCTION post_aggregates_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates (post_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates + WHERE post_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create trigger post_aggregates_post -after insert or delete on post -for each row -execute procedure post_aggregates_post(); +CREATE TRIGGER post_aggregates_post + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_post (); -- comment count -create function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1 - where pa.post_id = NEW.post_id; - - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time = NEW.published - where pa.post_id = NEW.post_id - and published > ('now'::timestamp - '2 days'::interval); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; +CREATE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1 + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id + AND published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; -create trigger post_aggregates_comment_count -after insert or delete on comment -for each row -execute procedure post_aggregates_comment_count(); +CREATE TRIGGER post_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_comment_count (); -- post score -create function post_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end - where pa.post_id = NEW.post_id; - - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - - END IF; - return null; -end $$; +CREATE FUNCTION post_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + pa.post_id = NEW.post_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; -create trigger post_aggregates_score -after insert or delete on post_like -for each row -execute procedure post_aggregates_score(); +CREATE TRIGGER post_aggregates_score + AFTER INSERT OR DELETE ON post_like + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_score (); -- post stickied -create function post_aggregates_stickied() -returns trigger language plpgsql -as $$ -begin - update post_aggregates pa - set stickied = NEW.stickied - where pa.post_id = NEW.id; +CREATE FUNCTION post_aggregates_stickied () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + post_aggregates pa + SET + stickied = NEW.stickied + WHERE + pa.post_id = NEW.id; + RETURN NULL; +END +$$; - return null; -end $$; +CREATE TRIGGER post_aggregates_stickied + AFTER UPDATE ON post + FOR EACH ROW + WHEN (OLD.stickied IS DISTINCT FROM NEW.stickied) + EXECUTE PROCEDURE post_aggregates_stickied (); -create trigger post_aggregates_stickied -after update on post -for each row -when (OLD.stickied is distinct from NEW.stickied) -execute procedure post_aggregates_stickied(); diff --git a/migrations/2020-12-14-020038_create_comment_aggregates/down.sql b/migrations/2020-12-14-020038_create_comment_aggregates/down.sql index 6fd9ddc2..1b3809ba 100644 --- a/migrations/2020-12-14-020038_create_comment_aggregates/down.sql +++ b/migrations/2020-12-14-020038_create_comment_aggregates/down.sql @@ -1,7 +1,9 @@ -- comment aggregates -drop table comment_aggregates; -drop trigger comment_aggregates_comment on comment; -drop trigger comment_aggregates_score on comment_like; -drop function - comment_aggregates_comment, - comment_aggregates_score; +DROP TABLE comment_aggregates; + +DROP TRIGGER comment_aggregates_comment ON comment; + +DROP TRIGGER comment_aggregates_score ON comment_like; + +DROP FUNCTION comment_aggregates_comment, comment_aggregates_score; + diff --git a/migrations/2020-12-14-020038_create_comment_aggregates/up.sql b/migrations/2020-12-14-020038_create_comment_aggregates/up.sql index f9cae6b3..25a9414f 100644 --- a/migrations/2020-12-14-020038_create_comment_aggregates/up.sql +++ b/migrations/2020-12-14-020038_create_comment_aggregates/up.sql @@ -1,84 +1,118 @@ -- Add comment aggregates -create table comment_aggregates ( - id serial primary key, - comment_id int references comment on update cascade on delete cascade not null, - score bigint not null default 0, - upvotes bigint not null default 0, - downvotes bigint not null default 0, - published timestamp not null default now(), - unique (comment_id) +CREATE TABLE comment_aggregates ( + id serial PRIMARY KEY, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + score bigint NOT NULL DEFAULT 0, + upvotes bigint NOT NULL DEFAULT 0, + downvotes bigint NOT NULL DEFAULT 0, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (comment_id) ); -insert into comment_aggregates (comment_id, score, upvotes, downvotes, published) - select +INSERT INTO comment_aggregates (comment_id, score, upvotes, downvotes, published) +SELECT c.id, COALESCE(cl.total, 0::bigint) AS score, COALESCE(cl.up, 0::bigint) AS upvotes, COALESCE(cl.down, 0::bigint) AS downvotes, c.published - from comment c - left join ( select l.comment_id as id, - sum(l.score) as total, - count( - case - when l.score = 1 then 1 - else null::integer - end) as up, - count( - case - when l.score = '-1'::integer then 1 - else null::integer - end) as down - from comment_like l - group by l.comment_id) cl on cl.id = c.id; +FROM + comment c + LEFT JOIN ( + SELECT + l.comment_id AS id, + sum(l.score) AS total, + count( + CASE WHEN l.score = 1 THEN + 1 + ELSE + NULL::integer + END) AS up, + count( + CASE WHEN l.score = '-1'::integer THEN + 1 + ELSE + NULL::integer + END) AS down + FROM + comment_like l + GROUP BY + l.comment_id) cl ON cl.id = c.id; -- Add comment aggregate triggers - -- initial comment add -create function comment_aggregates_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into comment_aggregates (comment_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from comment_aggregates where comment_id = OLD.id; - END IF; - return null; -end $$; +CREATE FUNCTION comment_aggregates_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates (comment_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates + WHERE comment_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create trigger comment_aggregates_comment -after insert or delete on comment -for each row -execute procedure comment_aggregates_comment(); +CREATE TRIGGER comment_aggregates_comment + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE comment_aggregates_comment (); -- comment score -create function comment_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update comment_aggregates ca - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end - where ca.comment_id = NEW.comment_id; - - ELSIF (TG_OP = 'DELETE') THEN - -- Join to comment because that comment may not exist anymore - update comment_aggregates ca - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end - from comment c - where ca.comment_id = c.id - and ca.comment_id = OLD.comment_id; +CREATE FUNCTION comment_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + comment_aggregates ca + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + ca.comment_id = NEW.comment_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to comment because that comment may not exist anymore + UPDATE + comment_aggregates ca + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END + FROM + comment c + WHERE + ca.comment_id = c.id + AND ca.comment_id = OLD.comment_id; + END IF; + RETURN NULL; +END +$$; - END IF; - return null; -end $$; +CREATE TRIGGER comment_aggregates_score + AFTER INSERT OR DELETE ON comment_like + FOR EACH ROW + EXECUTE PROCEDURE comment_aggregates_score (); -create trigger comment_aggregates_score -after insert or delete on comment_like -for each row -execute procedure comment_aggregates_score(); diff --git a/migrations/2020-12-17-030456_create_alias_views/down.sql b/migrations/2020-12-17-030456_create_alias_views/down.sql index 66ded96e..ac917269 100644 --- a/migrations/2020-12-17-030456_create_alias_views/down.sql +++ b/migrations/2020-12-17-030456_create_alias_views/down.sql @@ -1 +1,2 @@ -drop view user_alias_1, user_alias_2, comment_alias_1; +DROP VIEW user_alias_1, user_alias_2, comment_alias_1; + diff --git a/migrations/2020-12-17-030456_create_alias_views/up.sql b/migrations/2020-12-17-030456_create_alias_views/up.sql index 3d3b1b43..8eb35fc9 100644 --- a/migrations/2020-12-17-030456_create_alias_views/up.sql +++ b/migrations/2020-12-17-030456_create_alias_views/up.sql @@ -1,7 +1,21 @@ --- Some view that act as aliases +-- Some view that act as aliases -- unfortunately necessary, since diesel doesn't have self joins -- or alias support yet -create view user_alias_1 as select * from user_; -create view user_alias_2 as select * from user_; -create view comment_alias_1 as select * from comment; +CREATE VIEW user_alias_1 AS +SELECT + * +FROM + user_; + +CREATE VIEW user_alias_2 AS +SELECT + * +FROM + user_; + +CREATE VIEW comment_alias_1 AS +SELECT + * +FROM + comment; diff --git a/migrations/2020-12-17-031053_remove_fast_tables_and_views/down.sql b/migrations/2020-12-17-031053_remove_fast_tables_and_views/down.sql index 1c5d7767..275f4b61 100644 --- a/migrations/2020-12-17-031053_remove_fast_tables_and_views/down.sql +++ b/migrations/2020-12-17-031053_remove_fast_tables_and_views/down.sql @@ -1,4 +1,8 @@ -- There is no restore for this, it would require every view, table, index, etc. -- If you want to save past this point, you should make a DB backup. +SELECT + * +FROM + user_ +LIMIT 1; -select * from user_ limit 1; diff --git a/migrations/2020-12-17-031053_remove_fast_tables_and_views/up.sql b/migrations/2020-12-17-031053_remove_fast_tables_and_views/up.sql index cafa48ce..e7927737 100644 --- a/migrations/2020-12-17-031053_remove_fast_tables_and_views/up.sql +++ b/migrations/2020-12-17-031053_remove_fast_tables_and_views/up.sql @@ -1,64 +1,26 @@ -- Drop triggers -drop trigger if exists refresh_comment on comment; -drop trigger if exists refresh_comment_like on comment_like; -drop trigger if exists refresh_community on community; -drop trigger if exists refresh_community_follower on community_follower; -drop trigger if exists refresh_community_user_ban on community_user_ban; -drop trigger if exists refresh_post on post; -drop trigger if exists refresh_post_like on post_like; -drop trigger if exists refresh_user on user_; +DROP TRIGGER IF EXISTS refresh_comment ON comment; + +DROP TRIGGER IF EXISTS refresh_comment_like ON comment_like; + +DROP TRIGGER IF EXISTS refresh_community ON community; + +DROP TRIGGER IF EXISTS refresh_community_follower ON community_follower; + +DROP TRIGGER IF EXISTS refresh_community_user_ban ON community_user_ban; + +DROP TRIGGER IF EXISTS refresh_post ON post; + +DROP TRIGGER IF EXISTS refresh_post_like ON post_like; + +DROP TRIGGER IF EXISTS refresh_user ON user_; -- Drop functions -drop function if exists -refresh_comment, -refresh_comment_like, -refresh_community, -refresh_community_follower, -refresh_community_user_ban, -refresh_post, -refresh_post_like, -refresh_private_message, -refresh_user -cascade; +DROP FUNCTION IF EXISTS refresh_comment, refresh_comment_like, refresh_community, refresh_community_follower, refresh_community_user_ban, refresh_post, refresh_post_like, refresh_private_message, refresh_user CASCADE; -- Drop views -drop view if exists -comment_aggregates_view, -comment_fast_view, -comment_report_view, -comment_view, -community_aggregates_view, -community_fast_view, -community_follower_view, -community_moderator_view, -community_user_ban_view, -community_view, -mod_add_community_view, -mod_add_view, -mod_ban_from_community_view, -mod_ban_view, -mod_lock_post_view, -mod_remove_comment_view, -mod_remove_community_view, -mod_remove_post_view, -mod_sticky_post_view, -post_aggregates_view, -post_fast_view, -post_report_view, -post_view, -private_message_view, -reply_fast_view, -site_view, -user_mention_fast_view, -user_mention_view, -user_view -cascade; +DROP VIEW IF EXISTS comment_aggregates_view, comment_fast_view, comment_report_view, comment_view, community_aggregates_view, community_fast_view, community_follower_view, community_moderator_view, community_user_ban_view, community_view, mod_add_community_view, mod_add_view, mod_ban_from_community_view, mod_ban_view, mod_lock_post_view, mod_remove_comment_view, mod_remove_community_view, mod_remove_post_view, mod_sticky_post_view, post_aggregates_view, post_fast_view, post_report_view, post_view, private_message_view, reply_fast_view, site_view, user_mention_fast_view, user_mention_view, user_view CASCADE; -- Drop fast tables -drop table if exists -comment_aggregates_fast, -community_aggregates_fast, -post_aggregates_fast, -user_fast -cascade; +DROP TABLE IF EXISTS comment_aggregates_fast, community_aggregates_fast, post_aggregates_fast, user_fast CASCADE; diff --git a/migrations/2021-01-05-200932_add_hot_rank_indexes/down.sql b/migrations/2021-01-05-200932_add_hot_rank_indexes/down.sql index 55e83332..85267bf7 100644 --- a/migrations/2021-01-05-200932_add_hot_rank_indexes/down.sql +++ b/migrations/2021-01-05-200932_add_hot_rank_indexes/down.sql @@ -1,28 +1,13 @@ -- Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity -create or replace function hot_rank( - score numeric, - published timestamp without time zone) -returns integer as $$ -begin - -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 - return floor(10000*log(greatest(1,score+3)) / power(((EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600) + 2), 1.8))::integer; -end; $$ +CREATE OR REPLACE FUNCTION hot_rank (score numeric, published timestamp without time zone) + RETURNS integer + AS $$ +BEGIN + -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 + RETURN floor(10000 * log(greatest (1, score + 3)) / power(((EXTRACT(EPOCH FROM (timezone('utc', now()) - published)) / 3600) + 2), 1.8))::integer; +END; +$$ LANGUAGE plpgsql; -drop index - idx_post_aggregates_hot, - idx_post_aggregates_stickied_hot, - idx_post_aggregates_active, - idx_post_aggregates_stickied_active, - idx_post_aggregates_score, - idx_post_aggregates_stickied_score, - idx_post_aggregates_published, - idx_post_aggregates_stickied_published, - idx_comment_published, - idx_comment_aggregates_hot, - idx_comment_aggregates_score, - idx_user_published, - idx_user_aggregates_comment_score, - idx_community_published, - idx_community_aggregates_hot, - idx_community_aggregates_subscribers; +DROP INDEX idx_post_aggregates_hot, idx_post_aggregates_stickied_hot, idx_post_aggregates_active, idx_post_aggregates_stickied_active, idx_post_aggregates_score, idx_post_aggregates_stickied_score, idx_post_aggregates_published, idx_post_aggregates_stickied_published, idx_comment_published, idx_comment_aggregates_hot, idx_comment_aggregates_score, idx_user_published, idx_user_aggregates_comment_score, idx_community_published, idx_community_aggregates_hot, idx_community_aggregates_subscribers; + diff --git a/migrations/2021-01-05-200932_add_hot_rank_indexes/up.sql b/migrations/2021-01-05-200932_add_hot_rank_indexes/up.sql index f4d41471..88eb0f4b 100644 --- a/migrations/2021-01-05-200932_add_hot_rank_indexes/up.sql +++ b/migrations/2021-01-05-200932_add_hot_rank_indexes/up.sql @@ -1,49 +1,52 @@ -- Need to add immutable to the hot_rank function in order to index by it - -- Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity -create or replace function hot_rank( - score numeric, - published timestamp without time zone) -returns integer as $$ -begin - -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 - return floor(10000*log(greatest(1,score+3)) / power(((EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600) + 2), 1.8))::integer; -end; $$ +CREATE OR REPLACE FUNCTION hot_rank (score numeric, published timestamp without time zone) + RETURNS integer + AS $$ +BEGIN + -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 + RETURN floor(10000 * log(greatest (1, score + 3)) / power(((EXTRACT(EPOCH FROM (timezone('utc', now()) - published)) / 3600) + 2), 1.8))::integer; +END; +$$ LANGUAGE plpgsql IMMUTABLE; -- Post_aggregates -create index idx_post_aggregates_stickied_hot on post_aggregates (stickied desc, hot_rank(score, published) desc, published desc); -create index idx_post_aggregates_hot on post_aggregates (hot_rank(score, published) desc, published desc); +CREATE INDEX idx_post_aggregates_stickied_hot ON post_aggregates (stickied DESC, hot_rank (score, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_hot ON post_aggregates (hot_rank (score, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_stickied_active ON post_aggregates (stickied DESC, hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_active ON post_aggregates (hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); -create index idx_post_aggregates_stickied_active on post_aggregates (stickied desc, hot_rank(score, newest_comment_time) desc, newest_comment_time desc); -create index idx_post_aggregates_active on post_aggregates (hot_rank(score, newest_comment_time) desc, newest_comment_time desc); +CREATE INDEX idx_post_aggregates_stickied_score ON post_aggregates (stickied DESC, score DESC); -create index idx_post_aggregates_stickied_score on post_aggregates (stickied desc, score desc); -create index idx_post_aggregates_score on post_aggregates (score desc); +CREATE INDEX idx_post_aggregates_score ON post_aggregates (score DESC); -create index idx_post_aggregates_stickied_published on post_aggregates (stickied desc, published desc); -create index idx_post_aggregates_published on post_aggregates (published desc); +CREATE INDEX idx_post_aggregates_stickied_published ON post_aggregates (stickied DESC, published DESC); + +CREATE INDEX idx_post_aggregates_published ON post_aggregates (published DESC); -- Comment -create index idx_comment_published on comment (published desc); +CREATE INDEX idx_comment_published ON comment (published DESC); -- Comment_aggregates -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank(score, published) desc, published desc); -create index idx_comment_aggregates_score on comment_aggregates (score desc); +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank (score, published) DESC, published DESC); + +CREATE INDEX idx_comment_aggregates_score ON comment_aggregates (score DESC); -- User -create index idx_user_published on user_ (published desc); +CREATE INDEX idx_user_published ON user_ (published DESC); -- User_aggregates -create index idx_user_aggregates_comment_score on user_aggregates (comment_score desc); +CREATE INDEX idx_user_aggregates_comment_score ON user_aggregates (comment_score DESC); -- Community -create index idx_community_published on community (published desc); +CREATE INDEX idx_community_published ON community (published DESC); -- Community_aggregates -create index idx_community_aggregates_hot on community_aggregates (hot_rank(subscribers, published) desc, published desc); -create index idx_community_aggregates_subscribers on community_aggregates (subscribers desc); - +CREATE INDEX idx_community_aggregates_hot ON community_aggregates (hot_rank (subscribers, published) DESC, published DESC); +CREATE INDEX idx_community_aggregates_subscribers ON community_aggregates (subscribers DESC); diff --git a/migrations/2021-01-26-173850_default_actor_id/down.sql b/migrations/2021-01-26-173850_default_actor_id/down.sql index fb612743..80092cab 100644 --- a/migrations/2021-01-26-173850_default_actor_id/down.sql +++ b/migrations/2021-01-26-173850_default_actor_id/down.sql @@ -1,6 +1,10 @@ -create or replace function generate_unique_changeme() -returns text language sql -as $$ - select 'changeme_' || string_agg (substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil (random() * 62)::integer, 1), '') - from generate_series(1, 20) -$$; \ No newline at end of file +CREATE OR REPLACE FUNCTION generate_unique_changeme () + RETURNS text + LANGUAGE sql + AS $$ + SELECT + 'changeme_' || string_agg(substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil(random() * 62)::integer, 1), '') + FROM + generate_series(1, 20) +$$; + diff --git a/migrations/2021-01-26-173850_default_actor_id/up.sql b/migrations/2021-01-26-173850_default_actor_id/up.sql index 4370c4a5..00aa1c71 100644 --- a/migrations/2021-01-26-173850_default_actor_id/up.sql +++ b/migrations/2021-01-26-173850_default_actor_id/up.sql @@ -1,6 +1,10 @@ -create or replace function generate_unique_changeme() -returns text language sql -as $$ - select 'http://changeme_' || string_agg (substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil (random() * 62)::integer, 1), '') - from generate_series(1, 20) -$$; \ No newline at end of file +CREATE OR REPLACE FUNCTION generate_unique_changeme () + RETURNS text + LANGUAGE sql + AS $$ + SELECT + 'http://changeme_' || string_agg(substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil(random() * 62)::integer, 1), '') + FROM + generate_series(1, 20) +$$; + diff --git a/migrations/2021-01-27-202728_active_users_monthly/down.sql b/migrations/2021-01-27-202728_active_users_monthly/down.sql index bc3d46a5..e5d63689 100644 --- a/migrations/2021-01-27-202728_active_users_monthly/down.sql +++ b/migrations/2021-01-27-202728_active_users_monthly/down.sql @@ -1,14 +1,16 @@ -alter table site_aggregates - drop column users_active_day, - drop column users_active_week, - drop column users_active_month, - drop column users_active_half_year; - -alter table community_aggregates - drop column users_active_day, - drop column users_active_week, - drop column users_active_month, - drop column users_active_half_year; - -drop function site_aggregates_activity(i text); -drop function community_aggregates_activity(i text); +ALTER TABLE site_aggregates + DROP COLUMN users_active_day, + DROP COLUMN users_active_week, + DROP COLUMN users_active_month, + DROP COLUMN users_active_half_year; + +ALTER TABLE community_aggregates + DROP COLUMN users_active_day, + DROP COLUMN users_active_week, + DROP COLUMN users_active_month, + DROP COLUMN users_active_half_year; + +DROP FUNCTION site_aggregates_activity (i text); + +DROP FUNCTION community_aggregates_activity (i text); + diff --git a/migrations/2021-01-27-202728_active_users_monthly/up.sql b/migrations/2021-01-27-202728_active_users_monthly/up.sql index 9248ae86..63ca51d1 100644 --- a/migrations/2021-01-27-202728_active_users_monthly/up.sql +++ b/migrations/2021-01-27-202728_active_users_monthly/up.sql @@ -1,89 +1,162 @@ -- Add monthly and half yearly active columns for site and community aggregates - -- These columns don't need to be updated with a trigger, so they're saved daily via queries -alter table site_aggregates add column users_active_day bigint not null default 0; -alter table site_aggregates add column users_active_week bigint not null default 0; -alter table site_aggregates add column users_active_month bigint not null default 0; -alter table site_aggregates add column users_active_half_year bigint not null default 0; - -alter table community_aggregates add column users_active_day bigint not null default 0; -alter table community_aggregates add column users_active_week bigint not null default 0; -alter table community_aggregates add column users_active_month bigint not null default 0; -alter table community_aggregates add column users_active_half_year bigint not null default 0; - -create or replace function site_aggregates_activity(i text) -returns int -language plpgsql -as -$$ -declare - count_ integer; -begin - select count(*) - into count_ - from ( - select c.creator_id from comment c - inner join user_ 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 user_ u on p.creator_id = u.id - where p.published > ('now'::timestamp - i::interval) - and u.local = true - ) a; - return count_; -end; +ALTER TABLE site_aggregates + ADD COLUMN users_active_day bigint NOT NULL DEFAULT 0; + +ALTER TABLE site_aggregates + ADD COLUMN users_active_week bigint NOT NULL DEFAULT 0; + +ALTER TABLE site_aggregates + ADD COLUMN users_active_month bigint NOT NULL DEFAULT 0; + +ALTER TABLE site_aggregates + ADD COLUMN users_active_half_year bigint NOT NULL DEFAULT 0; + +ALTER TABLE community_aggregates + ADD COLUMN users_active_day bigint NOT NULL DEFAULT 0; + +ALTER TABLE community_aggregates + ADD COLUMN users_active_week bigint NOT NULL DEFAULT 0; + +ALTER TABLE community_aggregates + ADD COLUMN users_active_month bigint NOT NULL DEFAULT 0; + +ALTER TABLE community_aggregates + ADD COLUMN users_active_half_year bigint NOT NULL DEFAULT 0; + +CREATE OR REPLACE FUNCTION site_aggregates_activity (i text) + RETURNS int + LANGUAGE plpgsql + AS $$ +DECLARE + count_ integer; +BEGIN + SELECT + count(*) INTO count_ + FROM ( + SELECT + c.creator_id + FROM + comment c + INNER JOIN user_ 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 user_ u ON p.creator_id = u.id + WHERE + p.published > ('now'::timestamp - i::interval) + AND u.local = TRUE) a; + RETURN count_; +END; $$; -update site_aggregates -set users_active_day = (select * from site_aggregates_activity('1 day')); - -update site_aggregates -set users_active_week = (select * from site_aggregates_activity('1 week')); - -update site_aggregates -set users_active_month = (select * from site_aggregates_activity('1 month')); - -update site_aggregates -set users_active_half_year = (select * from site_aggregates_activity('6 months')); - -create or replace function community_aggregates_activity(i text) -returns table(count_ bigint, community_id_ integer) -language plpgsql -as -$$ -begin - return query - select count(*), community_id - from ( - select c.creator_id, p.community_id from comment c - inner join post p on c.post_id = p.id - where c.published > ('now'::timestamp - i::interval) - union - select p.creator_id, p.community_id from post p - where p.published > ('now'::timestamp - i::interval) - ) a - group by community_id; -end; +UPDATE + site_aggregates +SET + users_active_day = ( + SELECT + * + FROM + site_aggregates_activity ('1 day')); + +UPDATE + site_aggregates +SET + users_active_week = ( + SELECT + * + FROM + site_aggregates_activity ('1 week')); + +UPDATE + site_aggregates +SET + users_active_month = ( + SELECT + * + FROM + site_aggregates_activity ('1 month')); + +UPDATE + site_aggregates +SET + users_active_half_year = ( + SELECT + * + FROM + site_aggregates_activity ('6 months')); + +CREATE OR REPLACE FUNCTION community_aggregates_activity (i text) + RETURNS TABLE ( + count_ bigint, + community_id_ integer) + LANGUAGE plpgsql + AS $$ +BEGIN + RETURN query + SELECT + count(*), + community_id + FROM ( + SELECT + c.creator_id, + p.community_id + FROM + comment c + INNER JOIN post p ON c.post_id = p.id + WHERE + c.published > ('now'::timestamp - i::interval) + UNION + SELECT + p.creator_id, + p.community_id + FROM + post p + WHERE + p.published > ('now'::timestamp - i::interval)) a +GROUP BY + community_id; +END; $$; -update community_aggregates ca -set users_active_day = mv.count_ -from community_aggregates_activity('1 day') mv -where ca.community_id = mv.community_id_; - -update community_aggregates ca -set users_active_week = mv.count_ -from community_aggregates_activity('1 week') mv -where ca.community_id = mv.community_id_; - -update community_aggregates ca -set users_active_month = mv.count_ -from community_aggregates_activity('1 month') mv -where ca.community_id = mv.community_id_; - -update community_aggregates ca -set users_active_half_year = mv.count_ -from community_aggregates_activity('6 months') mv -where ca.community_id = mv.community_id_; +UPDATE + community_aggregates ca +SET + users_active_day = mv.count_ +FROM + community_aggregates_activity ('1 day') mv +WHERE + ca.community_id = mv.community_id_; + +UPDATE + community_aggregates ca +SET + users_active_week = mv.count_ +FROM + community_aggregates_activity ('1 week') mv +WHERE + ca.community_id = mv.community_id_; + +UPDATE + community_aggregates ca +SET + users_active_month = mv.count_ +FROM + community_aggregates_activity ('1 month') mv +WHERE + ca.community_id = mv.community_id_; + +UPDATE + community_aggregates ca +SET + users_active_half_year = mv.count_ +FROM + community_aggregates_activity ('6 months') mv +WHERE + ca.community_id = mv.community_id_; + diff --git a/migrations/2021-01-31-050334_add_forum_sort_index/down.sql b/migrations/2021-01-31-050334_add_forum_sort_index/down.sql index 9de29698..a81fc6c0 100644 --- a/migrations/2021-01-31-050334_add_forum_sort_index/down.sql +++ b/migrations/2021-01-31-050334_add_forum_sort_index/down.sql @@ -1 +1,2 @@ -drop index idx_post_aggregates_comments; +DROP INDEX idx_post_aggregates_comments; + diff --git a/migrations/2021-01-31-050334_add_forum_sort_index/up.sql b/migrations/2021-01-31-050334_add_forum_sort_index/up.sql index 61087388..18013f48 100644 --- a/migrations/2021-01-31-050334_add_forum_sort_index/up.sql +++ b/migrations/2021-01-31-050334_add_forum_sort_index/up.sql @@ -1 +1,2 @@ -create index idx_post_aggregates_comments on post_aggregates (comments desc); +CREATE INDEX idx_post_aggregates_comments ON post_aggregates (comments DESC); + diff --git a/migrations/2021-02-02-153240_apub_columns/down.sql b/migrations/2021-02-02-153240_apub_columns/down.sql index 248eb9b8..a5ff8edc 100644 --- a/migrations/2021-02-02-153240_apub_columns/down.sql +++ b/migrations/2021-02-02-153240_apub_columns/down.sql @@ -1,6 +1,15 @@ -ALTER TABLE community DROP COLUMN followers_url; -ALTER TABLE community DROP COLUMN inbox_url; -ALTER TABLE community DROP COLUMN shared_inbox_url; +ALTER TABLE community + DROP COLUMN followers_url; + +ALTER TABLE community + DROP COLUMN inbox_url; + +ALTER TABLE community + DROP COLUMN shared_inbox_url; + +ALTER TABLE user_ + DROP COLUMN inbox_url; + +ALTER TABLE user_ + DROP COLUMN shared_inbox_url; -ALTER TABLE user_ DROP COLUMN inbox_url; -ALTER TABLE user_ DROP COLUMN shared_inbox_url; \ No newline at end of file diff --git a/migrations/2021-02-02-153240_apub_columns/up.sql b/migrations/2021-02-02-153240_apub_columns/up.sql index 48f3b20e..69e99cb2 100644 --- a/migrations/2021-02-02-153240_apub_columns/up.sql +++ b/migrations/2021-02-02-153240_apub_columns/up.sql @@ -1,10 +1,24 @@ -ALTER TABLE community ADD COLUMN followers_url varchar(255) NOT NULL DEFAULT generate_unique_changeme(); -ALTER TABLE community ADD COLUMN inbox_url varchar(255) NOT NULL DEFAULT generate_unique_changeme(); -ALTER TABLE community ADD COLUMN shared_inbox_url varchar(255); +ALTER TABLE community + ADD COLUMN followers_url varchar(255) NOT NULL DEFAULT generate_unique_changeme (); -ALTER TABLE user_ ADD COLUMN inbox_url varchar(255) NOT NULL DEFAULT generate_unique_changeme(); -ALTER TABLE user_ ADD COLUMN shared_inbox_url varchar(255); +ALTER TABLE community + ADD COLUMN inbox_url varchar(255) NOT NULL DEFAULT generate_unique_changeme (); + +ALTER TABLE community + ADD COLUMN shared_inbox_url varchar(255); + +ALTER TABLE user_ + ADD COLUMN inbox_url varchar(255) NOT NULL DEFAULT generate_unique_changeme (); + +ALTER TABLE user_ + ADD COLUMN shared_inbox_url varchar(255); + +ALTER TABLE community + ADD CONSTRAINT idx_community_followers_url UNIQUE (followers_url); + +ALTER TABLE community + ADD CONSTRAINT idx_community_inbox_url UNIQUE (inbox_url); + +ALTER TABLE user_ + ADD CONSTRAINT idx_user_inbox_url UNIQUE (inbox_url); -ALTER TABLE community ADD CONSTRAINT idx_community_followers_url UNIQUE (followers_url); -ALTER TABLE community ADD CONSTRAINT idx_community_inbox_url UNIQUE (inbox_url); -ALTER TABLE user_ ADD CONSTRAINT idx_user_inbox_url UNIQUE (inbox_url); diff --git a/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql b/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql index 75f9aea3..acfd6d12 100644 --- a/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql +++ b/migrations/2021-02-10-164051_add_new_comments_sort_index/down.sql @@ -1,33 +1,43 @@ -drop index idx_post_aggregates_newest_comment_time, -idx_post_aggregates_stickied_newest_comment_time, -idx_post_aggregates_stickied_comments; +DROP INDEX idx_post_aggregates_newest_comment_time, idx_post_aggregates_stickied_newest_comment_time, idx_post_aggregates_stickied_comments; -alter table post_aggregates drop column newest_comment_time; +ALTER TABLE post_aggregates + DROP COLUMN newest_comment_time; -alter table post_aggregates rename column newest_comment_time_necro to newest_comment_time; +ALTER TABLE post_aggregates RENAME COLUMN newest_comment_time_necro TO newest_comment_time; -create or replace function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1 - where pa.post_id = NEW.post_id; - - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time = NEW.published - where pa.post_id = NEW.post_id - and published > ('now'::timestamp - '2 days'::interval); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1 + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id + AND published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; diff --git a/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql b/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql index 5452fbae..70d6f30a 100644 --- a/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql +++ b/migrations/2021-02-10-164051_add_new_comments_sort_index/up.sql @@ -1,43 +1,60 @@ -- First rename current newest comment time to newest_comment_time_necro -- necro means that time is limited to 2 days, whereas newest_comment_time ignores that. -alter table post_aggregates rename column newest_comment_time to newest_comment_time_necro; +ALTER TABLE post_aggregates RENAME COLUMN newest_comment_time TO newest_comment_time_necro; -- Add the newest_comment_time column -alter table post_aggregates add column newest_comment_time timestamp not null default now(); +ALTER TABLE post_aggregates + ADD COLUMN newest_comment_time timestamp NOT NULL DEFAULT now(); -- Set the current newest_comment_time based on the old ones -update post_aggregates set newest_comment_time = newest_comment_time_necro; +UPDATE + post_aggregates +SET + newest_comment_time = newest_comment_time_necro; -- Add the indexes for this new column -create index idx_post_aggregates_newest_comment_time on post_aggregates (newest_comment_time desc); -create index idx_post_aggregates_stickied_newest_comment_time on post_aggregates (stickied desc, newest_comment_time desc); +CREATE INDEX idx_post_aggregates_newest_comment_time ON post_aggregates (newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_stickied_newest_comment_time ON post_aggregates (stickied DESC, newest_comment_time DESC); -- Forgot to add index w/ stickied first for most comments: -create index idx_post_aggregates_stickied_comments on post_aggregates (stickied desc, comments desc); +CREATE INDEX idx_post_aggregates_stickied_comments ON post_aggregates (stickied DESC, comments DESC); -- Alter the comment trigger to set the newest_comment_time, and newest_comment_time_necro -create or replace function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1, - newest_comment_time = NEW.published - where pa.post_id = NEW.post_id; +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1, + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time_necro = NEW.published + WHERE + pa.post_id = NEW.post_id + AND published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time_necro = NEW.published - where pa.post_id = NEW.post_id - and published > ('now'::timestamp - '2 days'::interval); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; diff --git a/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/down.sql b/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/down.sql index 227c3ec2..94e981dd 100644 --- a/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/down.sql +++ b/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/down.sql @@ -1,35 +1,48 @@ -create or replace function comment_aggregates_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into comment_aggregates (comment_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from comment_aggregates where comment_id = OLD.id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION comment_aggregates_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates (comment_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates + WHERE comment_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create or replace function post_aggregates_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into post_aggregates (post_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from post_aggregates where post_id = OLD.id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION post_aggregates_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates (post_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates + WHERE post_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION community_aggregates_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates (community_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates + WHERE community_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create or replace function community_aggregates_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into community_aggregates (community_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from community_aggregates where community_id = OLD.id; - END IF; - return null; -end $$; diff --git a/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/up.sql b/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/up.sql index c195daad..9a942aa4 100644 --- a/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/up.sql +++ b/migrations/2021-02-13-210612_set_correct_aggregates_time_columns/up.sql @@ -1,39 +1,51 @@ --- The published and updated columns on the aggregates tables are using now(), +-- The published and updated columns on the aggregates tables are using now(), -- when they should use the correct published or updated columns -- This is mainly a problem with federated posts being fetched +CREATE OR REPLACE FUNCTION comment_aggregates_comment () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO comment_aggregates (comment_id, published) + VALUES (NEW.id, NEW.published); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM comment_aggregates + WHERE comment_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create or replace function comment_aggregates_comment() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into comment_aggregates (comment_id, published) values (NEW.id, NEW.published); - ELSIF (TG_OP = 'DELETE') THEN - delete from comment_aggregates where comment_id = OLD.id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION post_aggregates_post () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO post_aggregates (post_id, published, newest_comment_time, newest_comment_time_necro) + VALUES (NEW.id, NEW.published, NEW.published, NEW.published); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM post_aggregates + WHERE post_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create or replace function post_aggregates_post() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into post_aggregates (post_id, published, newest_comment_time, newest_comment_time_necro) values (NEW.id, NEW.published, NEW.published, NEW.published); - ELSIF (TG_OP = 'DELETE') THEN - delete from post_aggregates where post_id = OLD.id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION community_aggregates_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO community_aggregates (community_id, published) + VALUES (NEW.id, NEW.published); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM community_aggregates + WHERE community_id = OLD.id; + END IF; + RETURN NULL; +END +$$; -create or replace function community_aggregates_community() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into community_aggregates (community_id, published) values (NEW.id, NEW.published); - ELSIF (TG_OP = 'DELETE') THEN - delete from community_aggregates where community_id = OLD.id; - END IF; - return null; -end $$; diff --git a/migrations/2021-02-25-112959_remove-categories/down.sql b/migrations/2021-02-25-112959_remove-categories/down.sql index 35386f79..61d8c8d5 100644 --- a/migrations/2021-02-25-112959_remove-categories/down.sql +++ b/migrations/2021-02-25-112959_remove-categories/down.sql @@ -1,34 +1,36 @@ -create table category ( - id serial primary key, - name varchar(100) not null unique +CREATE TABLE category ( + id serial PRIMARY KEY, + name varchar(100) NOT NULL UNIQUE ); -insert into category (name) values -('Discussion'), -('Humor/Memes'), -('Gaming'), -('Movies'), -('TV'), -('Music'), -('Literature'), -('Comics'), -('Photography'), -('Art'), -('Learning'), -('DIY'), -('Lifestyle'), -('News'), -('Politics'), -('Society'), -('Gender/Identity/Sexuality'), -('Race/Colonisation'), -('Religion'), -('Science/Technology'), -('Programming/Software'), -('Health/Sports/Fitness'), -('Porn'), -('Places'), -('Meta'), -('Other'); +INSERT INTO category (name) + VALUES ('Discussion'), + ('Humor/Memes'), + ('Gaming'), + ('Movies'), + ('TV'), + ('Music'), + ('Literature'), + ('Comics'), + ('Photography'), + ('Art'), + ('Learning'), + ('DIY'), + ('Lifestyle'), + ('News'), + ('Politics'), + ('Society'), + ('Gender/Identity/Sexuality'), + ('Race/Colonisation'), + ('Religion'), + ('Science/Technology'), + ('Programming/Software'), + ('Health/Sports/Fitness'), + ('Porn'), + ('Places'), + ('Meta'), + ('Other'); + +ALTER TABLE community + ADD category_id int REFERENCES category ON UPDATE CASCADE ON DELETE CASCADE NOT NULL DEFAULT 1; -ALTER TABLE community ADD category_id int references category on update cascade on delete cascade not null default 1; \ No newline at end of file diff --git a/migrations/2021-02-25-112959_remove-categories/up.sql b/migrations/2021-02-25-112959_remove-categories/up.sql index ebe83e54..6b39bfe0 100644 --- a/migrations/2021-02-25-112959_remove-categories/up.sql +++ b/migrations/2021-02-25-112959_remove-categories/up.sql @@ -1,2 +1,5 @@ -ALTER TABLE community DROP COLUMN category_id; +ALTER TABLE community + DROP COLUMN category_id; + DROP TABLE category; + diff --git a/migrations/2021-02-28-162616_clean_empty_post_urls/down.sql b/migrations/2021-02-28-162616_clean_empty_post_urls/down.sql index 7195601c..0a9e8e2d 100644 --- a/migrations/2021-02-28-162616_clean_empty_post_urls/down.sql +++ b/migrations/2021-02-28-162616_clean_empty_post_urls/down.sql @@ -1,4 +1,5 @@ -- This is a clean-up migration that cannot be undone, -- but Diesel requires a non-empty script so run a no-op. -SELECT 1; +SELECT + 1; diff --git a/migrations/2021-02-28-162616_clean_empty_post_urls/up.sql b/migrations/2021-02-28-162616_clean_empty_post_urls/up.sql index 24e2d16b..5e091645 100644 --- a/migrations/2021-02-28-162616_clean_empty_post_urls/up.sql +++ b/migrations/2021-02-28-162616_clean_empty_post_urls/up.sql @@ -1 +1,7 @@ -UPDATE post SET url = NULL where url = ''; +UPDATE + post +SET + url = NULL +WHERE + url = ''; + diff --git a/migrations/2021-03-04-040229_clean_icon_urls/down.sql b/migrations/2021-03-04-040229_clean_icon_urls/down.sql index f866b155..0a9e8e2d 100644 --- a/migrations/2021-03-04-040229_clean_icon_urls/down.sql +++ b/migrations/2021-03-04-040229_clean_icon_urls/down.sql @@ -1,3 +1,5 @@ -- This is a clean-up migration that cannot be undone, -- but Diesel requires a non-empty script so run a no-op. -SELECT 1; +SELECT + 1; + diff --git a/migrations/2021-03-04-040229_clean_icon_urls/up.sql b/migrations/2021-03-04-040229_clean_icon_urls/up.sql index 8b22b33f..9fe28e8d 100644 --- a/migrations/2021-03-04-040229_clean_icon_urls/up.sql +++ b/migrations/2021-03-04-040229_clean_icon_urls/up.sql @@ -1,5 +1,29 @@ -- If these are not urls, it will crash the server -update user_ set avatar = NULL where avatar not like 'http%'; -update user_ set banner = NULL where banner not like 'http%'; -update community set icon = NULL where icon not like 'http%'; -update community set banner = NULL where banner not like 'http%'; +UPDATE + user_ +SET + avatar = NULL +WHERE + avatar NOT LIKE 'http%'; + +UPDATE + user_ +SET + banner = NULL +WHERE + banner NOT LIKE 'http%'; + +UPDATE + community +SET + icon = NULL +WHERE + icon NOT LIKE 'http%'; + +UPDATE + community +SET + banner = NULL +WHERE + banner NOT LIKE 'http%'; + diff --git a/migrations/2021-03-09-171136_split_user_table_2/down.sql b/migrations/2021-03-09-171136_split_user_table_2/down.sql index e1d55a20..cba90ac4 100644 --- a/migrations/2021-03-09-171136_split_user_table_2/down.sql +++ b/migrations/2021-03-09-171136_split_user_table_2/down.sql @@ -1,359 +1,503 @@ -- post_saved -alter table post_saved rename column person_id to user_id; -alter table post_saved rename constraint post_saved_post_id_person_id_key to post_saved_post_id_user_id_key; -alter table post_saved rename constraint post_saved_person_id_fkey to post_saved_user_id_fkey; +ALTER TABLE post_saved RENAME COLUMN person_id TO user_id; + +ALTER TABLE post_saved RENAME CONSTRAINT post_saved_post_id_person_id_key TO post_saved_post_id_user_id_key; + +ALTER TABLE post_saved RENAME CONSTRAINT post_saved_person_id_fkey TO post_saved_user_id_fkey; -- post_read -alter table post_read rename column person_id to user_id; -alter table post_read rename constraint post_read_post_id_person_id_key to post_read_post_id_user_id_key; -alter table post_read rename constraint post_read_person_id_fkey to post_read_user_id_fkey; +ALTER TABLE post_read RENAME COLUMN person_id TO user_id; + +ALTER TABLE post_read RENAME CONSTRAINT post_read_post_id_person_id_key TO post_read_post_id_user_id_key; + +ALTER TABLE post_read RENAME CONSTRAINT post_read_person_id_fkey TO post_read_user_id_fkey; -- post_like -alter table post_like rename column person_id to user_id; -alter index idx_post_like_person rename to idx_post_like_user; -alter table post_like rename constraint post_like_post_id_person_id_key to post_like_post_id_user_id_key; -alter table post_like rename constraint post_like_person_id_fkey to post_like_user_id_fkey; +ALTER TABLE post_like RENAME COLUMN person_id TO user_id; + +ALTER INDEX idx_post_like_person RENAME TO idx_post_like_user; + +ALTER TABLE post_like RENAME CONSTRAINT post_like_post_id_person_id_key TO post_like_post_id_user_id_key; + +ALTER TABLE post_like RENAME CONSTRAINT post_like_person_id_fkey TO post_like_user_id_fkey; -- password_reset_request -delete from password_reset_request; -alter table password_reset_request drop column local_user_id; -alter table password_reset_request add column user_id integer not null references person(id) on update cascade on delete cascade; +DELETE FROM password_reset_request; + +ALTER TABLE password_reset_request + DROP COLUMN local_user_id; + +ALTER TABLE password_reset_request + ADD COLUMN user_id integer NOT NULL REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE; -- mod_sticky_post -alter table mod_sticky_post rename column mod_person_id to mod_user_id; -alter table mod_sticky_post rename constraint mod_sticky_post_mod_person_id_fkey to mod_sticky_post_mod_user_id_fkey; +ALTER TABLE mod_sticky_post RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_sticky_post RENAME CONSTRAINT mod_sticky_post_mod_person_id_fkey TO mod_sticky_post_mod_user_id_fkey; -- mod_remove_post -alter table mod_remove_post rename column mod_person_id to mod_user_id; -alter table mod_remove_post rename constraint mod_remove_post_mod_person_id_fkey to mod_remove_post_mod_user_id_fkey; +ALTER TABLE mod_remove_post RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_remove_post RENAME CONSTRAINT mod_remove_post_mod_person_id_fkey TO mod_remove_post_mod_user_id_fkey; -- mod_remove_community -alter table mod_remove_community rename column mod_person_id to mod_user_id; -alter table mod_remove_community rename constraint mod_remove_community_mod_person_id_fkey to mod_remove_community_mod_user_id_fkey; +ALTER TABLE mod_remove_community RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_remove_community RENAME CONSTRAINT mod_remove_community_mod_person_id_fkey TO mod_remove_community_mod_user_id_fkey; -- mod_remove_comment -alter table mod_remove_comment rename column mod_person_id to mod_user_id; -alter table mod_remove_comment rename constraint mod_remove_comment_mod_person_id_fkey to mod_remove_comment_mod_user_id_fkey; +ALTER TABLE mod_remove_comment RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_remove_comment RENAME CONSTRAINT mod_remove_comment_mod_person_id_fkey TO mod_remove_comment_mod_user_id_fkey; -- mod_lock_post -alter table mod_lock_post rename column mod_person_id to mod_user_id; -alter table mod_lock_post rename constraint mod_lock_post_mod_person_id_fkey to mod_lock_post_mod_user_id_fkey; +ALTER TABLE mod_lock_post RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_lock_post RENAME CONSTRAINT mod_lock_post_mod_person_id_fkey TO mod_lock_post_mod_user_id_fkey; -- mod_add_community -alter table mod_ban_from_community rename column mod_person_id to mod_user_id; -alter table mod_ban_from_community rename column other_person_id to other_user_id; -alter table mod_ban_from_community rename constraint mod_ban_from_community_mod_person_id_fkey to mod_ban_from_community_mod_user_id_fkey; -alter table mod_ban_from_community rename constraint mod_ban_from_community_other_person_id_fkey to mod_ban_from_community_other_user_id_fkey; +ALTER TABLE mod_ban_from_community RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_ban_from_community RENAME COLUMN other_person_id TO other_user_id; + +ALTER TABLE mod_ban_from_community RENAME CONSTRAINT mod_ban_from_community_mod_person_id_fkey TO mod_ban_from_community_mod_user_id_fkey; + +ALTER TABLE mod_ban_from_community RENAME CONSTRAINT mod_ban_from_community_other_person_id_fkey TO mod_ban_from_community_other_user_id_fkey; -- mod_ban -alter table mod_ban rename column mod_person_id to mod_user_id; -alter table mod_ban rename column other_person_id to other_user_id; -alter table mod_ban rename constraint mod_ban_mod_person_id_fkey to mod_ban_mod_user_id_fkey; -alter table mod_ban rename constraint mod_ban_other_person_id_fkey to mod_ban_other_user_id_fkey; +ALTER TABLE mod_ban RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_ban RENAME COLUMN other_person_id TO other_user_id; + +ALTER TABLE mod_ban RENAME CONSTRAINT mod_ban_mod_person_id_fkey TO mod_ban_mod_user_id_fkey; + +ALTER TABLE mod_ban RENAME CONSTRAINT mod_ban_other_person_id_fkey TO mod_ban_other_user_id_fkey; -- mod_add_community -alter table mod_add_community rename column mod_person_id to mod_user_id; -alter table mod_add_community rename column other_person_id to other_user_id; -alter table mod_add_community rename constraint mod_add_community_mod_person_id_fkey to mod_add_community_mod_user_id_fkey; -alter table mod_add_community rename constraint mod_add_community_other_person_id_fkey to mod_add_community_other_user_id_fkey; +ALTER TABLE mod_add_community RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_add_community RENAME COLUMN other_person_id TO other_user_id; + +ALTER TABLE mod_add_community RENAME CONSTRAINT mod_add_community_mod_person_id_fkey TO mod_add_community_mod_user_id_fkey; + +ALTER TABLE mod_add_community RENAME CONSTRAINT mod_add_community_other_person_id_fkey TO mod_add_community_other_user_id_fkey; -- mod_add -alter table mod_add rename column mod_person_id to mod_user_id; -alter table mod_add rename column other_person_id to other_user_id; -alter table mod_add rename constraint mod_add_mod_person_id_fkey to mod_add_mod_user_id_fkey; -alter table mod_add rename constraint mod_add_other_person_id_fkey to mod_add_other_user_id_fkey; +ALTER TABLE mod_add RENAME COLUMN mod_person_id TO mod_user_id; + +ALTER TABLE mod_add RENAME COLUMN other_person_id TO other_user_id; + +ALTER TABLE mod_add RENAME CONSTRAINT mod_add_mod_person_id_fkey TO mod_add_mod_user_id_fkey; + +ALTER TABLE mod_add RENAME CONSTRAINT mod_add_other_person_id_fkey TO mod_add_other_user_id_fkey; -- community_user_ban -alter table community_person_ban rename to community_user_ban; -alter sequence community_person_ban_id_seq rename to community_user_ban_id_seq; -alter table community_user_ban rename column person_id to user_id; -alter table community_user_ban rename constraint community_person_ban_pkey to community_user_ban_pkey; -alter table community_user_ban rename constraint community_person_ban_community_id_fkey to community_user_ban_community_id_fkey; -alter table community_user_ban rename constraint community_person_ban_community_id_person_id_key to community_user_ban_community_id_user_id_key; -alter table community_user_ban rename constraint community_person_ban_person_id_fkey to community_user_ban_user_id_fkey; +ALTER TABLE community_person_ban RENAME TO community_user_ban; + +ALTER SEQUENCE community_person_ban_id_seq + RENAME TO community_user_ban_id_seq; + +ALTER TABLE community_user_ban RENAME COLUMN person_id TO user_id; + +ALTER TABLE community_user_ban RENAME CONSTRAINT community_person_ban_pkey TO community_user_ban_pkey; + +ALTER TABLE community_user_ban RENAME CONSTRAINT community_person_ban_community_id_fkey TO community_user_ban_community_id_fkey; + +ALTER TABLE community_user_ban RENAME CONSTRAINT community_person_ban_community_id_person_id_key TO community_user_ban_community_id_user_id_key; + +ALTER TABLE community_user_ban RENAME CONSTRAINT community_person_ban_person_id_fkey TO community_user_ban_user_id_fkey; -- community_moderator -alter table community_moderator rename column person_id to user_id; -alter table community_moderator rename constraint community_moderator_community_id_person_id_key to community_moderator_community_id_user_id_key; -alter table community_moderator rename constraint community_moderator_person_id_fkey to community_moderator_user_id_fkey; +ALTER TABLE community_moderator RENAME COLUMN person_id TO user_id; + +ALTER TABLE community_moderator RENAME CONSTRAINT community_moderator_community_id_person_id_key TO community_moderator_community_id_user_id_key; + +ALTER TABLE community_moderator RENAME CONSTRAINT community_moderator_person_id_fkey TO community_moderator_user_id_fkey; -- community_follower -alter table community_follower rename column person_id to user_id; -alter table community_follower rename constraint community_follower_community_id_person_id_key to community_follower_community_id_user_id_key; -alter table community_follower rename constraint community_follower_person_id_fkey to community_follower_user_id_fkey; +ALTER TABLE community_follower RENAME COLUMN person_id TO user_id; + +ALTER TABLE community_follower RENAME CONSTRAINT community_follower_community_id_person_id_key TO community_follower_community_id_user_id_key; + +ALTER TABLE community_follower RENAME CONSTRAINT community_follower_person_id_fkey TO community_follower_user_id_fkey; -- comment_saved -alter table comment_saved rename column person_id to user_id; -alter table comment_saved rename constraint comment_saved_comment_id_person_id_key to comment_saved_comment_id_user_id_key; -alter table comment_saved rename constraint comment_saved_person_id_fkey to comment_saved_user_id_fkey; +ALTER TABLE comment_saved RENAME COLUMN person_id TO user_id; + +ALTER TABLE comment_saved RENAME CONSTRAINT comment_saved_comment_id_person_id_key TO comment_saved_comment_id_user_id_key; + +ALTER TABLE comment_saved RENAME CONSTRAINT comment_saved_person_id_fkey TO comment_saved_user_id_fkey; -- comment_like -alter table comment_like rename column person_id to user_id; -alter index idx_comment_like_person rename to idx_comment_like_user; -alter table comment_like rename constraint comment_like_comment_id_person_id_key to comment_like_comment_id_user_id_key; -alter table comment_like rename constraint comment_like_person_id_fkey to comment_like_user_id_fkey; +ALTER TABLE comment_like RENAME COLUMN person_id TO user_id; + +ALTER INDEX idx_comment_like_person RENAME TO idx_comment_like_user; + +ALTER TABLE comment_like RENAME CONSTRAINT comment_like_comment_id_person_id_key TO comment_like_comment_id_user_id_key; + +ALTER TABLE comment_like RENAME CONSTRAINT comment_like_person_id_fkey TO comment_like_user_id_fkey; -- user_ban -alter table person_ban rename to user_ban; -alter sequence person_ban_id_seq rename to user_ban_id_seq; -alter index person_ban_pkey rename to user_ban_pkey; -alter index person_ban_person_id_key rename to user_ban_user_id_key; -alter table user_ban rename column person_id to user_id; -alter table user_ban rename constraint person_ban_person_id_fkey to user_ban_user_id_fkey; +ALTER TABLE person_ban RENAME TO user_ban; + +ALTER SEQUENCE person_ban_id_seq + RENAME TO user_ban_id_seq; + +ALTER INDEX person_ban_pkey RENAME TO user_ban_pkey; + +ALTER INDEX person_ban_person_id_key RENAME TO user_ban_user_id_key; + +ALTER TABLE user_ban RENAME COLUMN person_id TO user_id; + +ALTER TABLE user_ban RENAME CONSTRAINT person_ban_person_id_fkey TO user_ban_user_id_fkey; -- user_mention -alter table person_mention rename to user_mention; -alter sequence person_mention_id_seq rename to user_mention_id_seq; -alter index person_mention_pkey rename to user_mention_pkey; -alter index person_mention_recipient_id_comment_id_key rename to user_mention_recipient_id_comment_id_key; -alter table user_mention rename constraint person_mention_comment_id_fkey to user_mention_comment_id_fkey; -alter table user_mention rename constraint person_mention_recipient_id_fkey to user_mention_recipient_id_fkey; +ALTER TABLE person_mention RENAME TO user_mention; + +ALTER SEQUENCE person_mention_id_seq + RENAME TO user_mention_id_seq; + +ALTER INDEX person_mention_pkey RENAME TO user_mention_pkey; + +ALTER INDEX person_mention_recipient_id_comment_id_key RENAME TO user_mention_recipient_id_comment_id_key; + +ALTER TABLE user_mention RENAME CONSTRAINT person_mention_comment_id_fkey TO user_mention_comment_id_fkey; + +ALTER TABLE user_mention RENAME CONSTRAINT person_mention_recipient_id_fkey TO user_mention_recipient_id_fkey; -- User aggregates table -alter table person_aggregates rename to user_aggregates; -alter sequence person_aggregates_id_seq rename to user_aggregates_id_seq; -alter table user_aggregates rename column person_id to user_id; +ALTER TABLE person_aggregates RENAME TO user_aggregates; + +ALTER SEQUENCE person_aggregates_id_seq + RENAME TO user_aggregates_id_seq; + +ALTER TABLE user_aggregates RENAME COLUMN person_id TO user_id; -- Indexes -alter index person_aggregates_pkey rename to user_aggregates_pkey; -alter index idx_person_aggregates_comment_score rename to idx_user_aggregates_comment_score; -alter index person_aggregates_person_id_key rename to user_aggregates_user_id_key; -alter table user_aggregates rename constraint person_aggregates_person_id_fkey to user_aggregates_user_id_fkey; +ALTER INDEX person_aggregates_pkey RENAME TO user_aggregates_pkey; + +ALTER INDEX idx_person_aggregates_comment_score RENAME TO idx_user_aggregates_comment_score; + +ALTER INDEX person_aggregates_person_id_key RENAME TO user_aggregates_user_id_key; + +ALTER TABLE user_aggregates RENAME CONSTRAINT person_aggregates_person_id_fkey TO user_aggregates_user_id_fkey; -- Redo the user_aggregates table -drop trigger person_aggregates_person on person; -drop trigger person_aggregates_post_count on post; -drop trigger person_aggregates_post_score on post_like; -drop trigger person_aggregates_comment_count on comment; -drop trigger person_aggregates_comment_score on comment_like; -drop function - person_aggregates_person, - person_aggregates_post_count, - person_aggregates_post_score, - person_aggregates_comment_count, - person_aggregates_comment_score; +DROP TRIGGER person_aggregates_person ON person; + +DROP TRIGGER person_aggregates_post_count ON post; + +DROP TRIGGER person_aggregates_post_score ON post_like; + +DROP TRIGGER person_aggregates_comment_count ON comment; + +DROP TRIGGER person_aggregates_comment_score ON comment_like; + +DROP FUNCTION person_aggregates_person, person_aggregates_post_count, person_aggregates_post_score, person_aggregates_comment_count, person_aggregates_comment_score; -- user_ table -- Drop views -drop view person_alias_1, person_alias_2; +DROP VIEW person_alias_1, person_alias_2; -- Rename indexes -alter index person__pkey rename to user__pkey; -alter index idx_person_actor_id rename to idx_user_actor_id; -alter index idx_person_inbox_url rename to idx_user_inbox_url; -alter index idx_person_lower_actor_id rename to idx_user_lower_actor_id; -alter index idx_person_published rename to idx_user_published; +ALTER INDEX person__pkey RENAME TO user__pkey; + +ALTER INDEX idx_person_actor_id RENAME TO idx_user_actor_id; + +ALTER INDEX idx_person_inbox_url RENAME TO idx_user_inbox_url; + +ALTER INDEX idx_person_lower_actor_id RENAME TO idx_user_lower_actor_id; + +ALTER INDEX idx_person_published RENAME TO idx_user_published; -- Rename triggers -alter trigger site_aggregates_person_delete on person rename to site_aggregates_user_delete; -alter trigger site_aggregates_person_insert on person rename to site_aggregates_user_insert; +ALTER TRIGGER site_aggregates_person_delete ON person RENAME TO site_aggregates_user_delete; + +ALTER TRIGGER site_aggregates_person_insert ON person RENAME TO site_aggregates_user_insert; -- Rename the trigger functions -alter function site_aggregates_person_delete() rename to site_aggregates_user_delete; -alter function site_aggregates_person_insert() rename to site_aggregates_user_insert; +ALTER FUNCTION site_aggregates_person_delete () RENAME TO site_aggregates_user_delete; + +ALTER FUNCTION site_aggregates_person_insert () RENAME TO site_aggregates_user_insert; -- Rename the table back to user_ -alter table person rename to user_; -alter sequence person_id_seq rename to user__id_seq; +ALTER TABLE person RENAME TO user_; + +ALTER SEQUENCE person_id_seq + RENAME TO user__id_seq; -- Add the columns back in -alter table user_ - add column password_encrypted text not null default 'changeme', - add column email text, - add column admin boolean default false not null, - add column show_nsfw boolean default false not null, - add column theme character varying(20) default 'darkly'::character varying not null, - add column default_sort_type smallint default 0 not null, - add column default_listing_type smallint default 1 not null, - add column lang character varying(20) default 'browser'::character varying not null, - add column show_avatars boolean default true not null, - add column send_notifications_to_email boolean default false not null, - add column matrix_user_id text; +ALTER TABLE user_ + ADD COLUMN password_encrypted text NOT NULL DEFAULT 'changeme', + ADD COLUMN email text, + ADD COLUMN admin boolean DEFAULT FALSE NOT NULL, + ADD COLUMN show_nsfw boolean DEFAULT FALSE NOT NULL, + ADD COLUMN theme character varying(20) DEFAULT 'darkly'::character varying NOT NULL, + ADD COLUMN default_sort_type smallint DEFAULT 0 NOT NULL, + ADD COLUMN default_listing_type smallint DEFAULT 1 NOT NULL, + ADD COLUMN lang character varying(20) DEFAULT 'browser'::character varying NOT NULL, + ADD COLUMN show_avatars boolean DEFAULT TRUE NOT NULL, + ADD COLUMN send_notifications_to_email boolean DEFAULT FALSE NOT NULL, + ADD COLUMN matrix_user_id text; -- Update the user_ table with the local_user data -update user_ u set - password_encrypted = lu.password_encrypted, - email = lu.email, - admin = lu.admin, - show_nsfw = lu.show_nsfw, - theme = lu.theme, - default_sort_type = lu.default_sort_type, - default_listing_type = lu.default_listing_type, - lang = lu.lang, - show_avatars = lu.show_avatars, - send_notifications_to_email = lu.send_notifications_to_email, - matrix_user_id = lu.matrix_user_id -from local_user lu -where lu.person_id = u.id; - -create view user_alias_1 as select * from user_; -create view user_alias_2 as select * from user_; - -drop table local_user; +UPDATE + user_ u +SET + password_encrypted = lu.password_encrypted, + email = lu.email, + admin = lu.admin, + show_nsfw = lu.show_nsfw, + theme = lu.theme, + default_sort_type = lu.default_sort_type, + default_listing_type = lu.default_listing_type, + lang = lu.lang, + show_avatars = lu.show_avatars, + send_notifications_to_email = lu.send_notifications_to_email, + matrix_user_id = lu.matrix_user_id +FROM + local_user lu +WHERE + lu.person_id = u.id; + +CREATE VIEW user_alias_1 AS +SELECT + * +FROM + user_; + +CREATE VIEW user_alias_2 AS +SELECT + * +FROM + user_; + +DROP TABLE local_user; -- Add the user_aggregates table triggers - -- initial user add -create function user_aggregates_user() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into user_aggregates (user_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from user_aggregates where user_id = OLD.id; - END IF; - return null; -end $$; - -create trigger user_aggregates_user -after insert or delete on user_ -for each row -execute procedure user_aggregates_user(); +CREATE FUNCTION user_aggregates_user () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO user_aggregates (user_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM user_aggregates + WHERE user_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_user + AFTER INSERT OR DELETE ON user_ + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_user (); -- post count -create function user_aggregates_post_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update user_aggregates - set post_count = post_count + 1 where user_id = NEW.creator_id; - - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates - set post_count = post_count - 1 where user_id = OLD.creator_id; - - -- If the post gets deleted, the score calculation trigger won't fire, - -- so you need to re-calculate - update user_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 user_ 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.user_id = OLD.creator_id; - - END IF; - return null; -end $$; - -create trigger user_aggregates_post_count -after insert or delete on post -for each row -execute procedure user_aggregates_post_count(); +CREATE FUNCTION user_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + user_aggregates + SET + post_count = post_count + 1 + WHERE + user_id = NEW.creator_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates + SET + post_count = post_count - 1 + WHERE + user_id = OLD.creator_id; + -- If the post gets deleted, the score calculation trigger won't fire, + -- so you need to re-calculate + UPDATE + user_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 + user_ 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.user_id = OLD.creator_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_post_count + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_post_count (); -- post score -create function user_aggregates_post_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - -- Need to get the post creator, not the voter - update user_aggregates ua - set post_score = post_score + NEW.score - from post p - where ua.user_id = p.creator_id and p.id = NEW.post_id; - - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates ua - set post_score = post_score - OLD.score - from post p - where ua.user_id = p.creator_id and p.id = OLD.post_id; - END IF; - return null; -end $$; - -create trigger user_aggregates_post_score -after insert or delete on post_like -for each row -execute procedure user_aggregates_post_score(); +CREATE FUNCTION user_aggregates_post_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + -- Need to get the post creator, not the voter + UPDATE + user_aggregates ua + SET + post_score = post_score + NEW.score + FROM + post p + WHERE + ua.user_id = p.creator_id + AND p.id = NEW.post_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates ua + SET + post_score = post_score - OLD.score + FROM + post p + WHERE + ua.user_id = p.creator_id + AND p.id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_post_score + AFTER INSERT OR DELETE ON post_like + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_post_score (); -- comment count -create function user_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update user_aggregates - set comment_count = comment_count + 1 where user_id = NEW.creator_id; - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates - set comment_count = comment_count - 1 where user_id = OLD.creator_id; - - -- If the comment gets deleted, the score calculation trigger won't fire, - -- so you need to re-calculate - update user_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 user_ 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.user_id = OLD.creator_id; - END IF; - return null; -end $$; - -create trigger user_aggregates_comment_count -after insert or delete on comment -for each row -execute procedure user_aggregates_comment_count(); +CREATE FUNCTION user_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + user_aggregates + SET + comment_count = comment_count + 1 + WHERE + user_id = NEW.creator_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates + SET + comment_count = comment_count - 1 + WHERE + user_id = OLD.creator_id; + -- If the comment gets deleted, the score calculation trigger won't fire, + -- so you need to re-calculate + UPDATE + user_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 + user_ 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.user_id = OLD.creator_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_comment_count (); -- comment score -create function user_aggregates_comment_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - -- Need to get the post creator, not the voter - update user_aggregates ua - set comment_score = comment_score + NEW.score - from comment c - where ua.user_id = c.creator_id and c.id = NEW.comment_id; - ELSIF (TG_OP = 'DELETE') THEN - update user_aggregates ua - set comment_score = comment_score - OLD.score - from comment c - where ua.user_id = c.creator_id and c.id = OLD.comment_id; - END IF; - return null; -end $$; - -create trigger user_aggregates_comment_score -after insert or delete on comment_like -for each row -execute procedure user_aggregates_comment_score(); +CREATE FUNCTION user_aggregates_comment_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + -- Need to get the post creator, not the voter + UPDATE + user_aggregates ua + SET + comment_score = comment_score + NEW.score + FROM + comment c + WHERE + ua.user_id = c.creator_id + AND c.id = NEW.comment_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + user_aggregates ua + SET + comment_score = comment_score - OLD.score + FROM + comment c + WHERE + ua.user_id = c.creator_id + AND c.id = OLD.comment_id; + END IF; + RETURN NULL; +END +$$; + +CREATE TRIGGER user_aggregates_comment_score + AFTER INSERT OR DELETE ON comment_like + FOR EACH ROW + EXECUTE PROCEDURE user_aggregates_comment_score (); -- 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 user_ 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 user_ u on p.creator_id = u.id - where p.published > ('now'::timestamp - i::interval) - and u.local = true - ) a; - return count_; -end; +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 user_ 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 user_ u ON p.creator_id = u.id + WHERE + p.published > ('now'::timestamp - i::interval) + AND u.local = TRUE) a; + RETURN count_; +END; $$; + diff --git a/migrations/2021-03-09-171136_split_user_table_2/up.sql b/migrations/2021-03-09-171136_split_user_table_2/up.sql index db3547e5..4eb020d4 100644 --- a/migrations/2021-03-09-171136_split_user_table_2/up.sql +++ b/migrations/2021-03-09-171136_split_user_table_2/up.sql @@ -1,391 +1,519 @@ -- Person -- Drop the 2 views user_alias_1, user_alias_2 -drop view 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; +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) +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; +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; +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; +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; +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; +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; +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; +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; +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; +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(); +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(); +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(); +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(); +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(); +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; +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; $$; + diff --git a/migrations/2021-03-19-014144_add_col_local_user_validator_time/down.sql b/migrations/2021-03-19-014144_add_col_local_user_validator_time/down.sql index 657bfb3d..d59419bf 100644 --- a/migrations/2021-03-19-014144_add_col_local_user_validator_time/down.sql +++ b/migrations/2021-03-19-014144_add_col_local_user_validator_time/down.sql @@ -1 +1,3 @@ -alter table local_user drop column validator_time; +ALTER TABLE local_user + DROP COLUMN validator_time; + diff --git a/migrations/2021-03-19-014144_add_col_local_user_validator_time/up.sql b/migrations/2021-03-19-014144_add_col_local_user_validator_time/up.sql index 4fbb5eb9..3f3ac07a 100644 --- a/migrations/2021-03-19-014144_add_col_local_user_validator_time/up.sql +++ b/migrations/2021-03-19-014144_add_col_local_user_validator_time/up.sql @@ -1 +1,3 @@ -alter table local_user add column validator_time timestamp not null default now(); +ALTER TABLE local_user + ADD COLUMN validator_time timestamp NOT NULL DEFAULT now(); + diff --git a/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql b/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql index 990d8fe9..548dc9a0 100644 --- a/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql +++ b/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql @@ -1,17 +1,37 @@ -alter table local_user add column matrix_user_id text; -alter table local_user add column admin boolean default false not null; +ALTER TABLE local_user + ADD COLUMN matrix_user_id text; -update local_user lu -set - matrix_user_id = p.matrix_user_id, - admin = p.admin -from person p -where p.id = lu.person_id; +ALTER TABLE local_user + ADD COLUMN admin boolean DEFAULT FALSE NOT NULL; -drop view person_alias_1, person_alias_2; -alter table person drop column matrix_user_id; -alter table person drop column admin; +UPDATE + local_user lu +SET + matrix_user_id = p.matrix_user_id, + admin = p.admin +FROM + person p +WHERE + p.id = lu.person_id; + +DROP VIEW person_alias_1, person_alias_2; + +ALTER TABLE person + DROP COLUMN matrix_user_id; + +ALTER TABLE person + DROP COLUMN admin; -- Regenerate the person_alias views -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + diff --git a/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql b/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql index d9ba3dd9..7c7c1fb4 100644 --- a/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql +++ b/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql @@ -1,17 +1,37 @@ -alter table person add column matrix_user_id text; -alter table person add column admin boolean default false not null; +ALTER TABLE person + ADD COLUMN matrix_user_id text; -update person p -set - matrix_user_id = lu.matrix_user_id, - admin = lu.admin -from local_user lu -where p.id = lu.person_id; +ALTER TABLE person + ADD COLUMN admin boolean DEFAULT FALSE NOT NULL; -alter table local_user drop column matrix_user_id; -alter table local_user drop column admin; +UPDATE + person p +SET + matrix_user_id = lu.matrix_user_id, + admin = lu.admin +FROM + local_user lu +WHERE + p.id = lu.person_id; + +ALTER TABLE local_user + DROP COLUMN matrix_user_id; + +ALTER TABLE local_user + DROP COLUMN admin; -- Regenerate the person_alias views -drop view person_alias_1, person_alias_2; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +DROP VIEW person_alias_1, person_alias_2; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + diff --git a/migrations/2021-03-31-103917_add_show_score_setting/down.sql b/migrations/2021-03-31-103917_add_show_score_setting/down.sql index 9d35b563..20fc01c4 100644 --- a/migrations/2021-03-31-103917_add_show_score_setting/down.sql +++ b/migrations/2021-03-31-103917_add_show_score_setting/down.sql @@ -1 +1,3 @@ -alter table local_user drop column show_scores; +ALTER TABLE local_user + DROP COLUMN show_scores; + diff --git a/migrations/2021-03-31-103917_add_show_score_setting/up.sql b/migrations/2021-03-31-103917_add_show_score_setting/up.sql index 7960886a..94ca9bbd 100644 --- a/migrations/2021-03-31-103917_add_show_score_setting/up.sql +++ b/migrations/2021-03-31-103917_add_show_score_setting/up.sql @@ -1 +1,3 @@ -alter table local_user add column show_scores boolean default true not null; +ALTER TABLE local_user + ADD COLUMN show_scores boolean DEFAULT TRUE NOT NULL; + diff --git a/migrations/2021-03-31-105915_add_bot_account/down.sql b/migrations/2021-03-31-105915_add_bot_account/down.sql index 4f407ce8..d4d0ef04 100644 --- a/migrations/2021-03-31-105915_add_bot_account/down.sql +++ b/migrations/2021-03-31-105915_add_bot_account/down.sql @@ -1,6 +1,20 @@ -drop view person_alias_1, person_alias_2; -alter table person drop column bot_account; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +DROP VIEW person_alias_1, person_alias_2; + +ALTER TABLE person + DROP COLUMN bot_account; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + +ALTER TABLE local_user + DROP COLUMN show_bot_accounts; -alter table local_user drop column show_bot_accounts; diff --git a/migrations/2021-03-31-105915_add_bot_account/up.sql b/migrations/2021-03-31-105915_add_bot_account/up.sql index a1e207a1..7fc62811 100644 --- a/migrations/2021-03-31-105915_add_bot_account/up.sql +++ b/migrations/2021-03-31-105915_add_bot_account/up.sql @@ -1,8 +1,22 @@ -- Add the bot_account column to the person table -drop view person_alias_1, person_alias_2; -alter table person add column bot_account boolean not null default false; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +DROP VIEW person_alias_1, person_alias_2; + +ALTER TABLE person + ADD COLUMN bot_account boolean NOT NULL DEFAULT FALSE; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; -- Add the show_bot_accounts to the local user table as a setting -alter table local_user add column show_bot_accounts boolean not null default true; +ALTER TABLE local_user + ADD COLUMN show_bot_accounts boolean NOT NULL DEFAULT TRUE; + diff --git a/migrations/2021-03-31-144349_add_site_short_description/down.sql b/migrations/2021-03-31-144349_add_site_short_description/down.sql index 0035ee77..a1eab23d 100644 --- a/migrations/2021-03-31-144349_add_site_short_description/down.sql +++ b/migrations/2021-03-31-144349_add_site_short_description/down.sql @@ -1,2 +1,5 @@ -alter table site drop column description; -alter table site rename column sidebar to description; +ALTER TABLE site + DROP COLUMN description; + +ALTER TABLE site RENAME COLUMN sidebar TO description; + diff --git a/migrations/2021-03-31-144349_add_site_short_description/up.sql b/migrations/2021-03-31-144349_add_site_short_description/up.sql index 09dc36a7..14d63c88 100644 --- a/migrations/2021-03-31-144349_add_site_short_description/up.sql +++ b/migrations/2021-03-31-144349_add_site_short_description/up.sql @@ -1,5 +1,7 @@ -- Renaming description to sidebar -alter table site rename column description to sidebar; +ALTER TABLE site RENAME COLUMN description TO sidebar; -- Adding a short description column -alter table site add column description varchar(150); +ALTER TABLE site + ADD COLUMN description varchar(150); + diff --git a/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/down.sql b/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/down.sql index 844c02d3..112dc5b4 100644 --- a/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/down.sql +++ b/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/down.sql @@ -1,6 +1,17 @@ -alter table person rename display_name to preferred_username; +ALTER TABLE person RENAME display_name TO preferred_username; -- Regenerate the person_alias views -drop view person_alias_1, person_alias_2; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +DROP VIEW person_alias_1, person_alias_2; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + diff --git a/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/up.sql b/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/up.sql index f4b9729c..17110d32 100644 --- a/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/up.sql +++ b/migrations/2021-04-01-173552_rename_preferred_username_to_display_name/up.sql @@ -1,6 +1,17 @@ -alter table person rename preferred_username to display_name; +ALTER TABLE person RENAME preferred_username TO display_name; -- Regenerate the person_alias views -drop view person_alias_1, person_alias_2; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +DROP VIEW person_alias_1, person_alias_2; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + diff --git a/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/down.sql b/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/down.sql index 9748bc17..ba8cf93e 100644 --- a/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/down.sql +++ b/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/down.sql @@ -1 +1,2 @@ -drop index idx_community_aggregates_users_active_month; +DROP INDEX idx_community_aggregates_users_active_month; + diff --git a/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/up.sql b/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/up.sql index 4ae90e0a..57691250 100644 --- a/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/up.sql +++ b/migrations/2021-04-01-181826_add_community_agg_active_monthly_index/up.sql @@ -1,2 +1,2 @@ -create index idx_community_aggregates_users_active_month on community_aggregates (users_active_month desc); +CREATE INDEX idx_community_aggregates_users_active_month ON community_aggregates (users_active_month DESC); diff --git a/migrations/2021-04-02-021422_remove_community_creator/down.sql b/migrations/2021-04-02-021422_remove_community_creator/down.sql index d015f252..dc94ae36 100644 --- a/migrations/2021-04-02-021422_remove_community_creator/down.sql +++ b/migrations/2021-04-02-021422_remove_community_creator/down.sql @@ -1,24 +1,26 @@ - -- Add the column back -alter table community add column creator_id int references person on update cascade on delete cascade; +ALTER TABLE community + ADD COLUMN creator_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE; -- Recreate the index -create index idx_community_creator on community (creator_id); +CREATE INDEX idx_community_creator ON community (creator_id); -- Add the data, selecting the highest mod -update community -set creator_id = sub.person_id -from ( - select - cm.community_id, - cm.person_id - from - community_moderator cm - limit 1 -) as sub -where id = sub.community_id; +UPDATE + community +SET + creator_id = sub.person_id +FROM ( + SELECT + cm.community_id, + cm.person_id + FROM + community_moderator cm + LIMIT 1) AS sub +WHERE + id = sub.community_id; -- Set to not null -alter table community alter column creator_id set not null; - +ALTER TABLE community + ALTER COLUMN creator_id SET NOT NULL; diff --git a/migrations/2021-04-02-021422_remove_community_creator/up.sql b/migrations/2021-04-02-021422_remove_community_creator/up.sql index c3415c6a..cd41f86c 100644 --- a/migrations/2021-04-02-021422_remove_community_creator/up.sql +++ b/migrations/2021-04-02-021422_remove_community_creator/up.sql @@ -1,2 +1,4 @@ -- Drop the column -alter table community drop column creator_id; +ALTER TABLE community + DROP COLUMN creator_id; + diff --git a/migrations/2021-04-20-155001_limit-admins-create-community/down.sql b/migrations/2021-04-20-155001_limit-admins-create-community/down.sql index a04036f4..a1475fbd 100644 --- a/migrations/2021-04-20-155001_limit-admins-create-community/down.sql +++ b/migrations/2021-04-20-155001_limit-admins-create-community/down.sql @@ -1 +1,3 @@ -ALTER TABLE site DROP COLUMN community_creation_admin_only; +ALTER TABLE site + DROP COLUMN community_creation_admin_only; + diff --git a/migrations/2021-04-20-155001_limit-admins-create-community/up.sql b/migrations/2021-04-20-155001_limit-admins-create-community/up.sql index f302f88a..44d5be69 100644 --- a/migrations/2021-04-20-155001_limit-admins-create-community/up.sql +++ b/migrations/2021-04-20-155001_limit-admins-create-community/up.sql @@ -1 +1,3 @@ -ALTER TABLE site ADD COLUMN community_creation_admin_only bool NOT NULL DEFAULT false; +ALTER TABLE site + ADD COLUMN community_creation_admin_only bool NOT NULL DEFAULT FALSE; + diff --git a/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql b/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql index 2aa27514..040bbeb5 100644 --- a/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql +++ b/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql @@ -1 +1,3 @@ -alter table local_user drop column show_read_posts; +ALTER TABLE local_user + DROP COLUMN show_read_posts; + diff --git a/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql b/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql index 74b5398c..a5c26245 100644 --- a/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql +++ b/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql @@ -1 +1,3 @@ -alter table local_user add column show_read_posts boolean default true not null; +ALTER TABLE local_user + ADD COLUMN show_read_posts boolean DEFAULT TRUE NOT NULL; + diff --git a/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/down.sql b/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/down.sql index 197c36eb..60cf5106 100644 --- a/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/down.sql +++ b/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/down.sql @@ -1 +1,3 @@ -alter table local_user drop column show_new_post_notifs; +ALTER TABLE local_user + DROP COLUMN show_new_post_notifs; + diff --git a/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/up.sql b/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/up.sql index 7c6960b4..de5c6a72 100644 --- a/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/up.sql +++ b/migrations/2021-07-19-130929_add_show_new_post_notifs_setting/up.sql @@ -1 +1,3 @@ -alter table local_user add column show_new_post_notifs boolean default false not null; +ALTER TABLE local_user + ADD COLUMN show_new_post_notifs boolean DEFAULT FALSE NOT NULL; + diff --git a/migrations/2021-07-20-102033_actor_name_length/down.sql b/migrations/2021-07-20-102033_actor_name_length/down.sql index 76cec4c9..c8436ad8 100644 --- a/migrations/2021-07-20-102033_actor_name_length/down.sql +++ b/migrations/2021-07-20-102033_actor_name_length/down.sql @@ -1,10 +1,28 @@ DROP VIEW person_alias_1; + DROP VIEW person_alias_2; -ALTER TABLE community ALTER COLUMN name TYPE varchar(20); -ALTER TABLE community ALTER COLUMN title TYPE varchar(100); -ALTER TABLE person ALTER COLUMN name TYPE varchar(20); -ALTER TABLE person ALTER COLUMN display_name TYPE varchar(20); +ALTER TABLE community + ALTER COLUMN name TYPE varchar(20); + +ALTER TABLE community + ALTER COLUMN title TYPE varchar(100); + +ALTER TABLE person + ALTER COLUMN name TYPE varchar(20); + +ALTER TABLE person + ALTER COLUMN display_name TYPE varchar(20); + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; diff --git a/migrations/2021-07-20-102033_actor_name_length/up.sql b/migrations/2021-07-20-102033_actor_name_length/up.sql index 2e7bc9df..2db7c3b4 100644 --- a/migrations/2021-07-20-102033_actor_name_length/up.sql +++ b/migrations/2021-07-20-102033_actor_name_length/up.sql @@ -1,10 +1,28 @@ DROP VIEW person_alias_1; + DROP VIEW person_alias_2; -ALTER TABLE community ALTER COLUMN name TYPE varchar(255); -ALTER TABLE community ALTER COLUMN title TYPE varchar(255); -ALTER TABLE person ALTER COLUMN name TYPE varchar(255); -ALTER TABLE person ALTER COLUMN display_name TYPE varchar(255); +ALTER TABLE community + ALTER COLUMN name TYPE varchar(255); + +ALTER TABLE community + ALTER COLUMN title TYPE varchar(255); + +ALTER TABLE person + ALTER COLUMN name TYPE varchar(255); + +ALTER TABLE person + ALTER COLUMN display_name TYPE varchar(255); + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; diff --git a/migrations/2021-08-02-002342_comment_count_fixes/down.sql b/migrations/2021-08-02-002342_comment_count_fixes/down.sql index 3a895f70..79578462 100644 --- a/migrations/2021-08-02-002342_comment_count_fixes/down.sql +++ b/migrations/2021-08-02-002342_comment_count_fixes/down.sql @@ -1,28 +1,41 @@ -drop trigger post_aggregates_comment_set_deleted on comment; -drop function post_aggregates_comment_deleted; +DROP TRIGGER post_aggregates_comment_set_deleted ON comment; -create or replace function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1, - newest_comment_time = NEW.published - where pa.post_id = NEW.post_id; +DROP FUNCTION post_aggregates_comment_deleted; + +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1, + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time_necro = NEW.published + WHERE + pa.post_id = NEW.post_id + AND published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time_necro = NEW.published - where pa.post_id = NEW.post_id - and published > ('now'::timestamp - '2 days'::interval); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; diff --git a/migrations/2021-08-02-002342_comment_count_fixes/up.sql b/migrations/2021-08-02-002342_comment_count_fixes/up.sql index b65f6008..81edf344 100644 --- a/migrations/2021-08-02-002342_comment_count_fixes/up.sql +++ b/migrations/2021-08-02-002342_comment_count_fixes/up.sql @@ -1,61 +1,84 @@ -- Creating a new trigger for when comment.deleted is updated +CREATE OR REPLACE FUNCTION post_aggregates_comment_deleted () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF NEW.deleted = TRUE THEN + UPDATE + post_aggregates pa + SET + comments = comments - 1 + WHERE + pa.post_id = NEW.post_id; + ELSE + UPDATE + post_aggregates pa + SET + comments = comments + 1 + WHERE + pa.post_id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; -create or replace function post_aggregates_comment_deleted() -returns trigger language plpgsql -as $$ -begin - IF NEW.deleted = TRUE THEN - update post_aggregates pa - set comments = comments - 1 - where pa.post_id = NEW.post_id; - ELSE - update post_aggregates pa - set comments = comments + 1 - where pa.post_id = NEW.post_id; - END IF; - return null; -end $$; - -create trigger post_aggregates_comment_set_deleted -after update of deleted on comment -for each row -execute procedure post_aggregates_comment_deleted(); +CREATE TRIGGER post_aggregates_comment_set_deleted + AFTER UPDATE OF deleted ON comment + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_comment_deleted (); -- Fix issue with being able to necro-bump your own post -create or replace function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1, - newest_comment_time = NEW.published - where pa.post_id = NEW.post_id; - - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time_necro = NEW.published - from post p - where pa.post_id = p.id - and pa.post_id = NEW.post_id - -- Fix issue with being able to necro-bump your own post - and NEW.creator_id != p.creator_id - and pa.published > ('now'::timestamp - '2 days'::interval); +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1, + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time_necro = NEW.published + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = NEW.post_id + -- Fix issue with being able to necro-bump your own post + AND NEW.creator_id != p.creator_id + AND pa.published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - ELSIF (TG_OP = 'UPDATE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; diff --git a/migrations/2021-08-04-223559_create_user_community_block/down.sql b/migrations/2021-08-04-223559_create_user_community_block/down.sql index eb5a35e5..d7a18449 100644 --- a/migrations/2021-08-04-223559_create_user_community_block/down.sql +++ b/migrations/2021-08-04-223559_create_user_community_block/down.sql @@ -1,2 +1,4 @@ -drop table person_block; -drop table community_block; +DROP TABLE person_block; + +DROP TABLE community_block; + diff --git a/migrations/2021-08-04-223559_create_user_community_block/up.sql b/migrations/2021-08-04-223559_create_user_community_block/up.sql index cbcadc28..4e31196c 100644 --- a/migrations/2021-08-04-223559_create_user_community_block/up.sql +++ b/migrations/2021-08-04-223559_create_user_community_block/up.sql @@ -1,15 +1,16 @@ -create table person_block ( - id serial primary key, - person_id int references person on update cascade on delete cascade not null, - target_id int references person on update cascade on delete cascade not null, - published timestamp not null default now(), - unique(person_id, target_id) +CREATE TABLE person_block ( + id serial PRIMARY KEY, + person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + target_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (person_id, target_id) ); -create table community_block ( - id serial primary key, - person_id int references person on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - published timestamp not null default now(), - unique(person_id, community_id) +CREATE TABLE community_block ( + id serial PRIMARY KEY, + person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (person_id, community_id) ); + diff --git a/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/down.sql b/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/down.sql index a0ec4bdd..50ddcb3a 100644 --- a/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/down.sql +++ b/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/down.sql @@ -1,42 +1,64 @@ -create or replace function community_aggregates_activity(i text) -returns table(count_ bigint, community_id_ integer) -language plpgsql -as -$$ -begin - return query - select count(*), community_id - from ( - select c.creator_id, p.community_id from comment c - inner join post p on c.post_id = p.id - where c.published > ('now'::timestamp - i::interval) - union - select p.creator_id, p.community_id from post p - where p.published > ('now'::timestamp - i::interval) - ) a - group by community_id; -end; +CREATE OR REPLACE FUNCTION community_aggregates_activity (i text) + RETURNS TABLE ( + count_ bigint, + community_id_ integer) + LANGUAGE plpgsql + AS $$ +BEGIN + RETURN query + SELECT + count(*), + community_id + FROM ( + SELECT + c.creator_id, + p.community_id + FROM + comment c + INNER JOIN post p ON c.post_id = p.id + WHERE + c.published > ('now'::timestamp - i::interval) + UNION + SELECT + p.creator_id, + p.community_id + FROM + post p + WHERE + p.published > ('now'::timestamp - i::interval)) a +GROUP BY + community_id; +END; $$; -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; +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; $$; + diff --git a/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/up.sql b/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/up.sql index 2aafc369..26a49bd8 100644 --- a/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/up.sql +++ b/migrations/2021-08-16-004209_fix_remove_bots_from_aggregates/up.sql @@ -1,52 +1,73 @@ -- Make sure bots aren't included in aggregate counts - -create or replace function community_aggregates_activity(i text) -returns table(count_ bigint, community_id_ integer) -language plpgsql -as -$$ -begin - return query - select count(*), community_id - from ( - select c.creator_id, p.community_id from comment c - inner join post p on c.post_id = p.id - inner join person pe on c.creator_id = pe.id - where c.published > ('now'::timestamp - i::interval) - and pe.bot_account = false - union - select p.creator_id, p.community_id from post p - inner join person pe on p.creator_id = pe.id - where p.published > ('now'::timestamp - i::interval) - and pe.bot_account = false - ) a - group by community_id; -end; +CREATE OR REPLACE FUNCTION community_aggregates_activity (i text) + RETURNS TABLE ( + count_ bigint, + community_id_ integer) + LANGUAGE plpgsql + AS $$ +BEGIN + RETURN query + SELECT + count(*), + community_id + FROM ( + SELECT + c.creator_id, + p.community_id + FROM + comment c + INNER JOIN post p ON c.post_id = p.id + INNER JOIN person pe ON c.creator_id = pe.id + WHERE + c.published > ('now'::timestamp - i::interval) + AND pe.bot_account = FALSE + UNION + SELECT + p.creator_id, + p.community_id + FROM + post p + INNER JOIN person pe ON p.creator_id = pe.id + WHERE + p.published > ('now'::timestamp - i::interval) + AND pe.bot_account = FALSE) a +GROUP BY + community_id; +END; $$; -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 - inner join person pe on c.creator_id = pe.id - where c.published > ('now'::timestamp - i::interval) - and u.local = true - and pe.bot_account = false - union - select p.creator_id from post p - inner join person u on p.creator_id = u.id - inner join person pe on p.creator_id = pe.id - where p.published > ('now'::timestamp - i::interval) - and u.local = true - and pe.bot_account = false - ) a; - return count_; -end; +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 + INNER JOIN person pe ON c.creator_id = pe.id + WHERE + c.published > ('now'::timestamp - i::interval) + AND u.local = TRUE + AND pe.bot_account = FALSE + UNION + SELECT + p.creator_id + FROM + post p + INNER JOIN person u ON p.creator_id = u.id + INNER JOIN person pe ON p.creator_id = pe.id + WHERE + p.published > ('now'::timestamp - i::interval) + AND u.local = TRUE + AND pe.bot_account = FALSE) a; + RETURN count_; +END; $$; + diff --git a/migrations/2021-08-17-210508_create_mod_transfer_community/down.sql b/migrations/2021-08-17-210508_create_mod_transfer_community/down.sql index 8a2d8820..47745433 100644 --- a/migrations/2021-08-17-210508_create_mod_transfer_community/down.sql +++ b/migrations/2021-08-17-210508_create_mod_transfer_community/down.sql @@ -1 +1,2 @@ -drop table mod_transfer_community; +DROP TABLE mod_transfer_community; + diff --git a/migrations/2021-08-17-210508_create_mod_transfer_community/up.sql b/migrations/2021-08-17-210508_create_mod_transfer_community/up.sql index b43cf140..e023576d 100644 --- a/migrations/2021-08-17-210508_create_mod_transfer_community/up.sql +++ b/migrations/2021-08-17-210508_create_mod_transfer_community/up.sql @@ -1,9 +1,10 @@ -- Add the mod_transfer_community log table -create table mod_transfer_community ( - id serial primary key, - mod_person_id int references person on update cascade on delete cascade not null, - other_person_id int references person on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - removed boolean default false, - when_ timestamp not null default now() +CREATE TABLE mod_transfer_community ( + id serial PRIMARY KEY, + mod_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + other_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + removed boolean DEFAULT FALSE, + when_ timestamp NOT NULL DEFAULT now() ); + diff --git a/migrations/2021-09-20-112945_jwt-secret/down.sql b/migrations/2021-09-20-112945_jwt-secret/down.sql index 61b21fba..89350d96 100644 --- a/migrations/2021-09-20-112945_jwt-secret/down.sql +++ b/migrations/2021-09-20-112945_jwt-secret/down.sql @@ -1 +1,2 @@ -drop table secret; +DROP TABLE secret; + diff --git a/migrations/2021-09-20-112945_jwt-secret/up.sql b/migrations/2021-09-20-112945_jwt-secret/up.sql index e9af9ef5..85797c7f 100644 --- a/migrations/2021-09-20-112945_jwt-secret/up.sql +++ b/migrations/2021-09-20-112945_jwt-secret/up.sql @@ -1,9 +1,9 @@ -- generate a jwt secret -create extension if not exists pgcrypto; +CREATE EXTENSION IF NOT EXISTS pgcrypto; -create table secret( - id serial primary key, - jwt_secret varchar not null default gen_random_uuid() +CREATE TABLE secret ( + id serial PRIMARY KEY, + jwt_secret varchar NOT NULL DEFAULT gen_random_uuid () ); -insert into secret default values; +INSERT INTO secret DEFAULT VALUES; diff --git a/migrations/2021-10-01-141650_create_admin_purge/down.sql b/migrations/2021-10-01-141650_create_admin_purge/down.sql index 054923f6..c542fe77 100644 --- a/migrations/2021-10-01-141650_create_admin_purge/down.sql +++ b/migrations/2021-10-01-141650_create_admin_purge/down.sql @@ -1,4 +1,8 @@ -drop table admin_purge_person; -drop table admin_purge_community; -drop table admin_purge_post; -drop table admin_purge_comment; +DROP TABLE admin_purge_person; + +DROP TABLE admin_purge_community; + +DROP TABLE admin_purge_post; + +DROP TABLE admin_purge_comment; + diff --git a/migrations/2021-10-01-141650_create_admin_purge/up.sql b/migrations/2021-10-01-141650_create_admin_purge/up.sql index 1eb6b3f1..a67e12fe 100644 --- a/migrations/2021-10-01-141650_create_admin_purge/up.sql +++ b/migrations/2021-10-01-141650_create_admin_purge/up.sql @@ -1,31 +1,31 @@ -- Add the admin_purge tables - -create table admin_purge_person ( - id serial primary key, - admin_person_id int references person on update cascade on delete cascade not null, - reason text, - when_ timestamp not null default now() +CREATE TABLE admin_purge_person ( + id serial PRIMARY KEY, + admin_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + when_ timestamp NOT NULL DEFAULT now() ); -create table admin_purge_community ( - id serial primary key, - admin_person_id int references person on update cascade on delete cascade not null, - reason text, - when_ timestamp not null default now() +CREATE TABLE admin_purge_community ( + id serial PRIMARY KEY, + admin_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + when_ timestamp NOT NULL DEFAULT now() ); -create table admin_purge_post ( - id serial primary key, - admin_person_id int references person on update cascade on delete cascade not null, - community_id int references community on update cascade on delete cascade not null, - reason text, - when_ timestamp not null default now() +CREATE TABLE admin_purge_post ( + id serial PRIMARY KEY, + admin_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + when_ timestamp NOT NULL DEFAULT now() ); -create table admin_purge_comment ( - id serial primary key, - admin_person_id int references person on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - reason text, - when_ timestamp not null default now() +CREATE TABLE admin_purge_comment ( + id serial PRIMARY KEY, + admin_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + reason text, + when_ timestamp NOT NULL DEFAULT now() ); + diff --git a/migrations/2021-11-22-135324_add_activity_ap_id_index/down.sql b/migrations/2021-11-22-135324_add_activity_ap_id_index/down.sql index d2d3ad9d..664d6cfe 100644 --- a/migrations/2021-11-22-135324_add_activity_ap_id_index/down.sql +++ b/migrations/2021-11-22-135324_add_activity_ap_id_index/down.sql @@ -1,5 +1,7 @@ -alter table activity alter column ap_id drop not null; +ALTER TABLE activity + ALTER COLUMN ap_id DROP NOT NULL; -create unique index idx_activity_unique_apid on activity ((data ->> 'id'::text)); +CREATE UNIQUE INDEX idx_activity_unique_apid ON activity ((data ->> 'id'::text)); + +DROP INDEX idx_activity_ap_id; -drop index idx_activity_ap_id; diff --git a/migrations/2021-11-22-135324_add_activity_ap_id_index/up.sql b/migrations/2021-11-22-135324_add_activity_ap_id_index/up.sql index 84530508..6fa2cf56 100644 --- a/migrations/2021-11-22-135324_add_activity_ap_id_index/up.sql +++ b/migrations/2021-11-22-135324_add_activity_ap_id_index/up.sql @@ -1,22 +1,29 @@ - -- Delete the empty ap_ids -delete from activity where ap_id is null; +DELETE FROM activity +WHERE ap_id IS NULL; -- Make it required -alter table activity alter column ap_id set not null; +ALTER TABLE activity + ALTER COLUMN ap_id SET NOT NULL; -- Delete dupes, keeping the first one -delete from activity a using ( - select min(id) as id, ap_id - from activity - group by ap_id having count(*) > 1 -) b -where a.ap_id = b.ap_id -and a.id <> b.id; +DELETE FROM activity a USING ( + SELECT + min(id) AS id, + ap_id + FROM + activity + GROUP BY + ap_id + HAVING + count(*) > 1) b +WHERE + a.ap_id = b.ap_id + AND a.id <> b.id; -- The index -create unique index idx_activity_ap_id on activity(ap_id); +CREATE UNIQUE INDEX idx_activity_ap_id ON activity (ap_id); -- Drop the old index -drop index idx_activity_unique_apid; +DROP INDEX idx_activity_unique_apid; diff --git a/migrations/2021-11-22-143904_add_required_public_key/down.sql b/migrations/2021-11-22-143904_add_required_public_key/down.sql index 775d07d3..a6101d0a 100644 --- a/migrations/2021-11-22-143904_add_required_public_key/down.sql +++ b/migrations/2021-11-22-143904_add_required_public_key/down.sql @@ -1,2 +1,6 @@ -alter table community alter column public_key drop not null; -alter table person alter column public_key drop not null; +ALTER TABLE community + ALTER COLUMN public_key DROP NOT NULL; + +ALTER TABLE person + ALTER COLUMN public_key DROP NOT NULL; + diff --git a/migrations/2021-11-22-143904_add_required_public_key/up.sql b/migrations/2021-11-22-143904_add_required_public_key/up.sql index b2882561..7776f88c 100644 --- a/migrations/2021-11-22-143904_add_required_public_key/up.sql +++ b/migrations/2021-11-22-143904_add_required_public_key/up.sql @@ -1,7 +1,14 @@ -- Delete the empty public keys -delete from community where public_key is null; -delete from person where public_key is null; +DELETE FROM community +WHERE public_key IS NULL; + +DELETE FROM person +WHERE public_key IS NULL; -- Make it required -alter table community alter column public_key set not null; -alter table person alter column public_key set not null; +ALTER TABLE community + ALTER COLUMN public_key SET NOT NULL; + +ALTER TABLE person + ALTER COLUMN public_key SET NOT NULL; + diff --git a/migrations/2021-11-23-031528_add_report_published_index/down.sql b/migrations/2021-11-23-031528_add_report_published_index/down.sql index b5e9b51c..33b4fecf 100644 --- a/migrations/2021-11-23-031528_add_report_published_index/down.sql +++ b/migrations/2021-11-23-031528_add_report_published_index/down.sql @@ -1,2 +1,4 @@ -drop index idx_comment_report_published; -drop index idx_post_report_published; +DROP INDEX idx_comment_report_published; + +DROP INDEX idx_post_report_published; + diff --git a/migrations/2021-11-23-031528_add_report_published_index/up.sql b/migrations/2021-11-23-031528_add_report_published_index/up.sql index eb0c1220..33492419 100644 --- a/migrations/2021-11-23-031528_add_report_published_index/up.sql +++ b/migrations/2021-11-23-031528_add_report_published_index/up.sql @@ -1,2 +1,4 @@ -create index idx_comment_report_published on comment_report (published desc); -create index idx_post_report_published on post_report (published desc); +CREATE INDEX idx_comment_report_published ON comment_report (published DESC); + +CREATE INDEX idx_post_report_published ON post_report (published DESC); + diff --git a/migrations/2021-11-23-132840_email_verification/down.sql b/migrations/2021-11-23-132840_email_verification/down.sql index cd1eb7c2..0579873d 100644 --- a/migrations/2021-11-23-132840_email_verification/down.sql +++ b/migrations/2021-11-23-132840_email_verification/down.sql @@ -1,8 +1,16 @@ -- revert defaults from db for local user init -alter table local_user alter column theme set default 'darkly'; -alter table local_user alter column default_listing_type set default 1; +ALTER TABLE local_user + ALTER COLUMN theme SET DEFAULT 'darkly'; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type SET DEFAULT 1; -- remove tables and columns for optional email verification -alter table site drop column require_email_verification; -alter table local_user drop column email_verified; -drop table email_verification; +ALTER TABLE site + DROP COLUMN require_email_verification; + +ALTER TABLE local_user + DROP COLUMN email_verified; + +DROP TABLE email_verification; + diff --git a/migrations/2021-11-23-132840_email_verification/up.sql b/migrations/2021-11-23-132840_email_verification/up.sql index 29a20e00..3b14b2a3 100644 --- a/migrations/2021-11-23-132840_email_verification/up.sql +++ b/migrations/2021-11-23-132840_email_verification/up.sql @@ -1,14 +1,21 @@ -- use defaults from db for local user init -alter table local_user alter column theme set default 'browser'; -alter table local_user alter column default_listing_type set default 2; +ALTER TABLE local_user + ALTER COLUMN theme SET DEFAULT 'browser'; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type SET DEFAULT 2; -- add tables and columns for optional email verification -alter table site add column require_email_verification boolean not null default false; -alter table local_user add column email_verified boolean not null default false; - -create table email_verification ( - id serial primary key, - local_user_id int references local_user(id) on update cascade on delete cascade not null, - email text not null, - verification_token text not null +ALTER TABLE site + ADD COLUMN require_email_verification boolean NOT NULL DEFAULT FALSE; + +ALTER TABLE local_user + ADD COLUMN email_verified boolean NOT NULL DEFAULT FALSE; + +CREATE TABLE email_verification ( + id serial PRIMARY KEY, + local_user_id int REFERENCES local_user (id) ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + email text NOT NULL, + verification_token text NOT NULL ); + diff --git a/migrations/2021-11-23-153753_add_invite_only_columns/down.sql b/migrations/2021-11-23-153753_add_invite_only_columns/down.sql index 52a1a280..22af54bf 100644 --- a/migrations/2021-11-23-153753_add_invite_only_columns/down.sql +++ b/migrations/2021-11-23-153753_add_invite_only_columns/down.sql @@ -1,9 +1,16 @@ -- Add columns to site table -alter table site drop column require_application; -alter table site drop column application_question; -alter table site drop column private_instance; +ALTER TABLE site + DROP COLUMN require_application; + +ALTER TABLE site + DROP COLUMN application_question; + +ALTER TABLE site + DROP COLUMN private_instance; -- Add pending to local_user -alter table local_user drop column accepted_application; +ALTER TABLE local_user + DROP COLUMN accepted_application; + +DROP TABLE registration_application; -drop table registration_application; diff --git a/migrations/2021-11-23-153753_add_invite_only_columns/up.sql b/migrations/2021-11-23-153753_add_invite_only_columns/up.sql index b3f8a18d..7e611b16 100644 --- a/migrations/2021-11-23-153753_add_invite_only_columns/up.sql +++ b/migrations/2021-11-23-153753_add_invite_only_columns/up.sql @@ -1,19 +1,26 @@ -- Add columns to site table -alter table site add column require_application boolean not null default false; -alter table site add column application_question text; -alter table site add column private_instance boolean not null default false; +ALTER TABLE site + ADD COLUMN require_application boolean NOT NULL DEFAULT FALSE; + +ALTER TABLE site + ADD COLUMN application_question text; + +ALTER TABLE site + ADD COLUMN private_instance boolean NOT NULL DEFAULT FALSE; -- Add pending to local_user -alter table local_user add column accepted_application boolean not null default false; +ALTER TABLE local_user + ADD COLUMN accepted_application boolean NOT NULL DEFAULT FALSE; -create table registration_application ( - id serial primary key, - local_user_id int references local_user on update cascade on delete cascade not null, - answer text not null, - admin_id int references person on update cascade on delete cascade, - deny_reason text, - published timestamp not null default now(), - unique(local_user_id) +CREATE TABLE registration_application ( + id serial PRIMARY KEY, + local_user_id int REFERENCES local_user ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + answer text NOT NULL, + admin_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE, + deny_reason text, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (local_user_id) ); -create index idx_registration_application_published on registration_application (published desc); +CREATE INDEX idx_registration_application_published ON registration_application (published DESC); + diff --git a/migrations/2021-12-09-225529_add_published_to_email_verification/down.sql b/migrations/2021-12-09-225529_add_published_to_email_verification/down.sql index 21405db1..64aaa8e0 100644 --- a/migrations/2021-12-09-225529_add_published_to_email_verification/down.sql +++ b/migrations/2021-12-09-225529_add_published_to_email_verification/down.sql @@ -1 +1,3 @@ -alter table email_verification drop column published; +ALTER TABLE email_verification + DROP COLUMN published; + diff --git a/migrations/2021-12-09-225529_add_published_to_email_verification/up.sql b/migrations/2021-12-09-225529_add_published_to_email_verification/up.sql index 79dd32bf..6eb47af6 100644 --- a/migrations/2021-12-09-225529_add_published_to_email_verification/up.sql +++ b/migrations/2021-12-09-225529_add_published_to_email_verification/up.sql @@ -1 +1,3 @@ -alter table email_verification add column published timestamp not null default now(); +ALTER TABLE email_verification + ADD COLUMN published timestamp NOT NULL DEFAULT now(); + diff --git a/migrations/2021-12-14-181537_add_temporary_bans/down.sql b/migrations/2021-12-14-181537_add_temporary_bans/down.sql index 83a3715e..fde33ab1 100644 --- a/migrations/2021-12-14-181537_add_temporary_bans/down.sql +++ b/migrations/2021-12-14-181537_add_temporary_bans/down.sql @@ -1,7 +1,20 @@ -drop view person_alias_1, person_alias_2; +DROP VIEW person_alias_1, person_alias_2; -alter table person drop column ban_expires; -alter table community_person_ban drop column expires; +ALTER TABLE person + DROP COLUMN ban_expires; + +ALTER TABLE community_person_ban + DROP COLUMN expires; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; diff --git a/migrations/2021-12-14-181537_add_temporary_bans/up.sql b/migrations/2021-12-14-181537_add_temporary_bans/up.sql index 7e633836..6b3ee246 100644 --- a/migrations/2021-12-14-181537_add_temporary_bans/up.sql +++ b/migrations/2021-12-14-181537_add_temporary_bans/up.sql @@ -1,8 +1,21 @@ -- Add ban_expires to person, community_person_ban -alter table person add column ban_expires timestamp; -alter table community_person_ban add column expires timestamp; +ALTER TABLE person + ADD COLUMN ban_expires timestamp; -drop view person_alias_1, person_alias_2; -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +ALTER TABLE community_person_ban + ADD COLUMN expires timestamp; + +DROP VIEW person_alias_1, person_alias_2; + +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; diff --git a/migrations/2022-01-04-034553_add_hidden_column/down.sql b/migrations/2022-01-04-034553_add_hidden_column/down.sql index 55a054ae..f6e9367c 100644 --- a/migrations/2022-01-04-034553_add_hidden_column/down.sql +++ b/migrations/2022-01-04-034553_add_hidden_column/down.sql @@ -1,3 +1,5 @@ -alter table community drop column hidden; +ALTER TABLE community + DROP COLUMN hidden; + +DROP TABLE mod_hide_community; -drop table mod_hide_community; diff --git a/migrations/2022-01-04-034553_add_hidden_column/up.sql b/migrations/2022-01-04-034553_add_hidden_column/up.sql index b7436616..8aa7321e 100644 --- a/migrations/2022-01-04-034553_add_hidden_column/up.sql +++ b/migrations/2022-01-04-034553_add_hidden_column/up.sql @@ -1,13 +1,12 @@ -alter table community add column hidden boolean default false; +ALTER TABLE community + ADD COLUMN hidden boolean DEFAULT FALSE; - -create table mod_hide_community -( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - mod_person_id int references person on update cascade on delete cascade not null, - when_ timestamp not null default now(), +CREATE TABLE mod_hide_community ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + mod_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + when_ timestamp NOT NULL DEFAULT now(), reason text, - hidden boolean default false + hidden boolean DEFAULT FALSE ); diff --git a/migrations/2022-01-20-160328_remove_site_creator/down.sql b/migrations/2022-01-20-160328_remove_site_creator/down.sql index 8195f719..612a5189 100644 --- a/migrations/2022-01-20-160328_remove_site_creator/down.sql +++ b/migrations/2022-01-20-160328_remove_site_creator/down.sql @@ -1,14 +1,22 @@ -- Add the column back -alter table site add column creator_id int references person on update cascade on delete cascade; +ALTER TABLE site + ADD COLUMN creator_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE; -- Add the data, selecting the highest admin -update site -set creator_id = sub.id -from ( - select id from person - where admin = true - limit 1 -) as sub; +UPDATE + site +SET + creator_id = sub.id +FROM ( + SELECT + id + FROM + person + WHERE + admin = TRUE + LIMIT 1) AS sub; -- Set to not null -alter table site alter column creator_id set not null; +ALTER TABLE site + ALTER COLUMN creator_id SET NOT NULL; + diff --git a/migrations/2022-01-20-160328_remove_site_creator/up.sql b/migrations/2022-01-20-160328_remove_site_creator/up.sql index 78774445..5f11c56c 100644 --- a/migrations/2022-01-20-160328_remove_site_creator/up.sql +++ b/migrations/2022-01-20-160328_remove_site_creator/up.sql @@ -1,2 +1,4 @@ -- Drop the column -alter table site drop column creator_id; +ALTER TABLE site + DROP COLUMN creator_id; + diff --git a/migrations/2022-01-28-104106_instance-actor/down.sql b/migrations/2022-01-28-104106_instance-actor/down.sql index a258c27a..0a45515d 100644 --- a/migrations/2022-01-28-104106_instance-actor/down.sql +++ b/migrations/2022-01-28-104106_instance-actor/down.sql @@ -1,6 +1,7 @@ -alter table site - drop column actor_id, - drop column last_refreshed_at, - drop column inbox_url, - drop column private_key, - drop column public_key; +ALTER TABLE site + DROP COLUMN actor_id, + DROP COLUMN last_refreshed_at, + DROP COLUMN inbox_url, + DROP COLUMN private_key, + DROP COLUMN public_key; + diff --git a/migrations/2022-01-28-104106_instance-actor/up.sql b/migrations/2022-01-28-104106_instance-actor/up.sql index 914ab757..dcbb0862 100644 --- a/migrations/2022-01-28-104106_instance-actor/up.sql +++ b/migrations/2022-01-28-104106_instance-actor/up.sql @@ -1,6 +1,7 @@ -alter table site - add column actor_id varchar(255) not null unique default generate_unique_changeme(), - add column last_refreshed_at Timestamp not null default now(), - add column inbox_url varchar(255) not null default generate_unique_changeme(), - add column private_key text, - add column public_key text not null default generate_unique_changeme(); +ALTER TABLE site + ADD COLUMN actor_id varchar(255) NOT NULL UNIQUE DEFAULT generate_unique_changeme (), + ADD COLUMN last_refreshed_at Timestamp NOT NULL DEFAULT now(), + ADD COLUMN inbox_url varchar(255) NOT NULL DEFAULT generate_unique_changeme (), + ADD COLUMN private_key text, + ADD COLUMN public_key text NOT NULL DEFAULT generate_unique_changeme (); + diff --git a/migrations/2022-02-01-154240_add_community_title_index/down.sql b/migrations/2022-02-01-154240_add_community_title_index/down.sql index 8b927b7b..39c454ab 100644 --- a/migrations/2022-02-01-154240_add_community_title_index/down.sql +++ b/migrations/2022-02-01-154240_add_community_title_index/down.sql @@ -1 +1,2 @@ -drop index idx_community_title; +DROP INDEX idx_community_title; + diff --git a/migrations/2022-02-01-154240_add_community_title_index/up.sql b/migrations/2022-02-01-154240_add_community_title_index/up.sql index 50c267bb..4fe52718 100644 --- a/migrations/2022-02-01-154240_add_community_title_index/up.sql +++ b/migrations/2022-02-01-154240_add_community_title_index/up.sql @@ -1 +1,2 @@ -create index idx_community_title on community(title); +CREATE INDEX idx_community_title ON community (title); + diff --git a/migrations/2022-02-18-210946_default_theme/down.sql b/migrations/2022-02-18-210946_default_theme/down.sql index fc57669a..a52305af 100644 --- a/migrations/2022-02-18-210946_default_theme/down.sql +++ b/migrations/2022-02-18-210946_default_theme/down.sql @@ -1 +1,3 @@ -alter table site drop column default_theme; \ No newline at end of file +ALTER TABLE site + DROP COLUMN default_theme; + diff --git a/migrations/2022-02-18-210946_default_theme/up.sql b/migrations/2022-02-18-210946_default_theme/up.sql index dd6faad4..f2a2822a 100644 --- a/migrations/2022-02-18-210946_default_theme/up.sql +++ b/migrations/2022-02-18-210946_default_theme/up.sql @@ -1 +1,3 @@ -alter table site add column default_theme text not null default 'browser'; \ No newline at end of file +ALTER TABLE site + ADD COLUMN default_theme text NOT NULL DEFAULT 'browser'; + diff --git a/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/down.sql b/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/down.sql index 8a8ea5cb..406d459a 100644 --- a/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/down.sql +++ b/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/down.sql @@ -1,254 +1,339 @@ -drop trigger if exists community_aggregates_post_count on post; -drop trigger if exists community_aggregates_comment_count on comment; -drop trigger if exists site_aggregates_comment_insert on comment; -drop trigger if exists site_aggregates_comment_delete on comment; -drop trigger if exists site_aggregates_post_insert on post; -drop trigger if exists site_aggregates_post_delete on post; -drop trigger if exists site_aggregates_community_insert on community; -drop trigger if exists site_aggregates_community_delete on community; -drop trigger if exists person_aggregates_post_count on post; -drop trigger if exists person_aggregates_comment_count on comment; - -drop function was_removed_or_deleted(TG_OP text, OLD record, NEW record); -drop function was_restored_or_created(TG_OP text, OLD record, NEW record); +DROP TRIGGER IF EXISTS community_aggregates_post_count ON post; --- Community aggregate functions +DROP TRIGGER IF EXISTS community_aggregates_comment_count ON comment; -create or replace function community_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN -update community_aggregates -set posts = posts + 1 where community_id = NEW.community_id; -ELSIF (TG_OP = 'DELETE') THEN -update community_aggregates -set posts = posts - 1 where community_id = OLD.community_id; - --- Update the counts if the post got deleted -update community_aggregates ca -set posts = coalesce(cd.posts, 0), - comments = coalesce(cd.comments, 0) - from ( - select - c.id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from community c - left join post p on c.id = p.community_id - left join comment ct on p.id = ct.post_id - group by c.id - ) cd -where ca.community_id = OLD.community_id; -END IF; -return null; -end $$; - -create or replace function community_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN -update community_aggregates ca -set comments = comments + 1 from comment c, post p -where p.id = c.post_id - and p.id = NEW.post_id - and ca.community_id = p.community_id; -ELSIF (TG_OP = 'DELETE') THEN -update community_aggregates ca -set comments = comments - 1 from comment c, post p -where p.id = c.post_id - and p.id = OLD.post_id - and ca.community_id = p.community_id; - -END IF; -return null; -end $$; +DROP TRIGGER IF EXISTS site_aggregates_comment_insert ON comment; --- Community aggregate triggers +DROP TRIGGER IF EXISTS site_aggregates_comment_delete ON comment; -create trigger community_aggregates_post_count - after insert or delete on post -for each row -execute procedure community_aggregates_post_count(); +DROP TRIGGER IF EXISTS site_aggregates_post_insert ON post; -create trigger community_aggregates_comment_count - after insert or delete on comment -for each row -execute procedure community_aggregates_comment_count(); +DROP TRIGGER IF EXISTS site_aggregates_post_delete ON post; --- Site aggregate functions +DROP TRIGGER IF EXISTS site_aggregates_community_insert ON community; -create or replace function site_aggregates_post_insert() - returns trigger language plpgsql -as $$ -begin -update site_aggregates -set posts = posts + 1; -return null; -end $$; - -create or replace function site_aggregates_post_delete() - returns trigger language plpgsql -as $$ -begin -update site_aggregates sa -set posts = posts - 1 - from site s -where sa.site_id = s.id; -return null; -end $$; - -create or replace function site_aggregates_comment_insert() - returns trigger language plpgsql -as $$ -begin -update site_aggregates -set comments = comments + 1; -return null; -end $$; - -create or replace function site_aggregates_comment_delete() - returns trigger language plpgsql -as $$ -begin -update site_aggregates sa -set comments = comments - 1 - from site s -where sa.site_id = s.id; -return null; -end $$; - -create or replace function site_aggregates_community_insert() - returns trigger language plpgsql -as $$ -begin -update site_aggregates -set communities = communities + 1; -return null; -end $$; - -create or replace function site_aggregates_community_delete() - returns trigger language plpgsql -as $$ -begin -update site_aggregates sa -set communities = communities - 1 - from site s -where sa.site_id = s.id; -return null; -end $$; +DROP TRIGGER IF EXISTS site_aggregates_community_delete ON community; +DROP TRIGGER IF EXISTS person_aggregates_post_count ON post; --- Site update triggers +DROP TRIGGER IF EXISTS person_aggregates_comment_count ON comment; -create trigger site_aggregates_post_insert - after insert on post - for each row - when (NEW.local = true) - execute procedure site_aggregates_post_insert(); - -create trigger site_aggregates_post_delete - after delete on post - for each row - when (OLD.local = true) - execute procedure site_aggregates_post_delete(); - -create trigger site_aggregates_comment_insert - after insert on comment - for each row - when (NEW.local = true) - execute procedure site_aggregates_comment_insert(); - -create trigger site_aggregates_comment_delete - after delete on comment - for each row - when (OLD.local = true) - execute procedure site_aggregates_comment_delete(); - -create trigger site_aggregates_community_insert - after insert on community - for each row - when (NEW.local = true) - execute procedure site_aggregates_community_insert(); - -create trigger site_aggregates_community_delete - after delete on community - for each row - when (OLD.local = true) - execute procedure site_aggregates_community_delete(); +DROP FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record); --- Person aggregate functions +DROP FUNCTION was_restored_or_created (TG_OP text, OLD record, NEW record); -create or replace function person_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin +-- Community aggregate functions +CREATE OR REPLACE FUNCTION community_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 or replace function person_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin + UPDATE + community_aggregates + SET + posts = posts + 1 + WHERE + community_id = NEW.community_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates + SET + posts = posts - 1 + WHERE + community_id = OLD.community_id; + -- Update the counts if the post got deleted + UPDATE + community_aggregates ca + SET + posts = coalesce(cd.posts, 0), + comments = coalesce(cd.comments, 0) + FROM ( + SELECT + c.id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + community c + LEFT JOIN post p ON c.id = p.community_id + LEFT JOIN comment ct ON p.id = ct.post_id + GROUP BY + c.id) cd + WHERE + ca.community_id = OLD.community_id; + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION community_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 $$; + UPDATE + community_aggregates ca + SET + comments = comments + 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = NEW.post_id + AND ca.community_id = p.community_id; + ELSIF (TG_OP = 'DELETE') THEN + UPDATE + community_aggregates ca + SET + comments = comments - 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = OLD.post_id + AND ca.community_id = p.community_id; + END IF; + RETURN NULL; +END +$$; + +-- Community aggregate triggers +CREATE TRIGGER community_aggregates_post_count + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_post_count (); +CREATE TRIGGER community_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_comment_count (); + +-- Site aggregate functions +CREATE OR REPLACE FUNCTION site_aggregates_post_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + posts = posts + 1; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_post_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + posts = posts - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_comment_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + comments = comments + 1; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_comment_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + comments = comments - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_community_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates + SET + communities = communities + 1; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_community_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + site_aggregates sa + SET + communities = communities - 1 + FROM + site s + WHERE + sa.site_id = s.id; + RETURN NULL; +END +$$; + +-- Site update triggers +CREATE TRIGGER site_aggregates_post_insert + AFTER INSERT ON post + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_insert (); + +CREATE TRIGGER site_aggregates_post_delete + AFTER DELETE ON post + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_delete (); + +CREATE TRIGGER site_aggregates_comment_insert + AFTER INSERT ON comment + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_insert (); + +CREATE TRIGGER site_aggregates_comment_delete + AFTER DELETE ON comment + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_delete (); + +CREATE TRIGGER site_aggregates_community_insert + AFTER INSERT ON community + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_insert (); + +CREATE TRIGGER site_aggregates_community_delete + AFTER DELETE ON community + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_delete (); + +-- Person aggregate functions +CREATE OR REPLACE 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 OR REPLACE 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 +$$; -- Person aggregate triggers +CREATE TRIGGER person_aggregates_post_count + AFTER INSERT OR DELETE ON post + FOR EACH ROW + EXECUTE PROCEDURE person_aggregates_post_count (); -create trigger person_aggregates_post_count - after insert or delete on post - for each row -execute procedure person_aggregates_post_count(); +CREATE TRIGGER person_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE person_aggregates_comment_count (); -create trigger person_aggregates_comment_count - after insert or delete on comment - for each row -execute procedure person_aggregates_comment_count(); \ No newline at end of file diff --git a/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/up.sql b/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/up.sql index 472be541..27fc66d1 100644 --- a/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/up.sql +++ b/migrations/2022-04-04-183652_update_community_aggregates_on_soft_delete/up.sql @@ -1,327 +1,445 @@ -drop trigger if exists community_aggregates_post_count on post; -drop trigger if exists community_aggregates_comment_count on comment; -drop trigger if exists site_aggregates_comment_insert on comment; -drop trigger if exists site_aggregates_comment_delete on comment; -drop trigger if exists site_aggregates_post_insert on post; -drop trigger if exists site_aggregates_post_delete on post; -drop trigger if exists site_aggregates_community_insert on community; -drop trigger if exists site_aggregates_community_delete on community; -drop trigger if exists person_aggregates_post_count on post; -drop trigger if exists person_aggregates_comment_count on comment; - -create or replace function was_removed_or_deleted(TG_OP text, OLD record, NEW record) -RETURNS boolean -LANGUAGE plpgsql -as $$ - begin - IF (TG_OP = 'INSERT') THEN - return false; - end if; - - IF (TG_OP = 'DELETE') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 'f' AND NEW.deleted = 't') OR - (OLD.removed = 'f' AND NEW.removed = 't') - ); -END $$; - -create or replace function was_restored_or_created(TG_OP text, OLD record, NEW record) - RETURNS boolean - LANGUAGE plpgsql -as $$ -begin - IF (TG_OP = 'DELETE') THEN - return false; - end if; +DROP TRIGGER IF EXISTS community_aggregates_post_count ON post; - IF (TG_OP = 'INSERT') THEN - return true; - end if; +DROP TRIGGER IF EXISTS community_aggregates_comment_count ON comment; - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 't' AND NEW.deleted = 'f') OR - (OLD.removed = 't' AND NEW.removed = 'f') - ); -END $$; +DROP TRIGGER IF EXISTS site_aggregates_comment_insert ON comment; --- Community aggregate functions +DROP TRIGGER IF EXISTS site_aggregates_comment_delete ON comment; -create or replace function community_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN -update community_aggregates -set posts = posts + 1 where community_id = NEW.community_id; - -IF (TG_OP = 'UPDATE') THEN - -- Post was restored, so restore comment counts as well - update community_aggregates ca - set posts = coalesce(cd.posts, 0), - comments = coalesce(cd.comments, 0) - from ( - select - c.id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from community c - left join post p on c.id = p.community_id and p.deleted = 'f' and p.removed = 'f' - left join comment ct on p.id = ct.post_id and ct.deleted = 'f' and ct.removed = 'f' - where c.id = NEW.community_id - group by c.id - ) cd - where ca.community_id = NEW.community_id; -END IF; - -ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN -update community_aggregates -set posts = posts - 1 where community_id = OLD.community_id; - --- Update the counts if the post got deleted -update community_aggregates ca -set posts = coalesce(cd.posts, 0), - comments = coalesce(cd.comments, 0) - from ( - select - c.id, - count(distinct p.id) as posts, - count(distinct ct.id) as comments - from community c - left join post p on c.id = p.community_id and p.deleted = 'f' and p.removed = 'f' - left join comment ct on p.id = ct.post_id and ct.deleted = 'f' and ct.removed = 'f' - where c.id = OLD.community_id - group by c.id - ) cd -where ca.community_id = OLD.community_id; -END IF; -return null; -end $$; +DROP TRIGGER IF EXISTS site_aggregates_post_insert ON post; --- comment count -create or replace function community_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments + 1 from comment c, post p -where p.id = c.post_id - and p.id = NEW.post_id - and ca.community_id = p.community_id; -ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments - 1 from comment c, post p -where p.id = c.post_id - and p.id = OLD.post_id - and ca.community_id = p.community_id; - -END IF; -return null; -end $$; +DROP TRIGGER IF EXISTS site_aggregates_post_delete ON post; --- Community aggregate triggers +DROP TRIGGER IF EXISTS site_aggregates_community_insert ON community; -create trigger community_aggregates_post_count - after insert or delete or update of removed, deleted on post - for each row -execute procedure community_aggregates_post_count(); +DROP TRIGGER IF EXISTS site_aggregates_community_delete ON community; -create trigger community_aggregates_comment_count - after insert or delete or update of removed, deleted on comment -for each row -execute procedure community_aggregates_comment_count(); +DROP TRIGGER IF EXISTS person_aggregates_post_count ON post; --- Site aggregate functions +DROP TRIGGER IF EXISTS person_aggregates_comment_count ON comment; -create or replace function site_aggregates_post_insert() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set posts = posts + 1 - from site s - where sa.site_id = s.id; +CREATE OR REPLACE FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + RETURN FALSE; END IF; - return null; -end $$; - -create or replace function site_aggregates_post_delete() - returns trigger language plpgsql -as $$ -begin - IF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set posts = posts - 1 - from site s - where sa.site_id = s.id; + IF (TG_OP = 'DELETE') THEN + RETURN TRUE; END IF; - return null; -end $$; - -create or replace function site_aggregates_comment_insert() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set comments = comments + 1 - from site s - where sa.site_id = s.id; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 'f' + AND NEW.deleted = 't') + OR (OLD.removed = 'f' + AND NEW.removed = 't')); +END +$$; + +CREATE OR REPLACE FUNCTION was_restored_or_created (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'DELETE') THEN + RETURN FALSE; END IF; - return null; -end $$; - -create or replace function site_aggregates_comment_delete() - returns trigger language plpgsql -as $$ -begin - IF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set comments = comments - 1 - from site s - where sa.site_id = s.id; + IF (TG_OP = 'INSERT') THEN + RETURN TRUE; END IF; - return null; -end $$; - -create or replace function site_aggregates_community_insert() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set communities = communities + 1 - from site s - where sa.site_id = s.id; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 't' + AND NEW.deleted = 'f') + OR (OLD.removed = 't' + AND NEW.removed = 'f')); +END +$$; + +-- Community aggregate functions +CREATE OR REPLACE FUNCTION community_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates + SET + posts = posts + 1 + WHERE + community_id = NEW.community_id; + IF (TG_OP = 'UPDATE') THEN + -- Post was restored, so restore comment counts as well + UPDATE + community_aggregates ca + SET + posts = coalesce(cd.posts, 0), + comments = coalesce(cd.comments, 0) + FROM ( + SELECT + c.id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + community c + LEFT JOIN post p ON c.id = p.community_id + AND p.deleted = 'f' + AND p.removed = 'f' + LEFT JOIN comment ct ON p.id = ct.post_id + AND ct.deleted = 'f' + AND ct.removed = 'f' + WHERE + c.id = NEW.community_id + GROUP BY + c.id) cd + WHERE + ca.community_id = NEW.community_id; + END IF; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates + SET + posts = posts - 1 + WHERE + community_id = OLD.community_id; + -- Update the counts if the post got deleted + UPDATE + community_aggregates ca + SET + posts = coalesce(cd.posts, 0), + comments = coalesce(cd.comments, 0) + FROM ( + SELECT + c.id, + count(DISTINCT p.id) AS posts, + count(DISTINCT ct.id) AS comments + FROM + community c + LEFT JOIN post p ON c.id = p.community_id + AND p.deleted = 'f' + AND p.removed = 'f' + LEFT JOIN comment ct ON p.id = ct.post_id + AND ct.deleted = 'f' + AND ct.removed = 'f' + WHERE + c.id = OLD.community_id + GROUP BY + c.id) cd + WHERE + ca.community_id = OLD.community_id; END IF; - return null; -end $$; - -create or replace function site_aggregates_community_delete() - returns trigger language plpgsql -as $$ -begin - IF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update site_aggregates sa - set communities = communities - 1 - from site s - where sa.site_id = s.id; + RETURN NULL; +END +$$; + +-- comment count +CREATE OR REPLACE FUNCTION community_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments + 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = NEW.post_id + AND ca.community_id = p.community_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments - 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = OLD.post_id + AND ca.community_id = p.community_id; END IF; - return null; -end $$; + RETURN NULL; +END +$$; --- Site aggregate triggers +-- Community aggregate triggers +CREATE TRIGGER community_aggregates_post_count + AFTER INSERT OR DELETE OR UPDATE OF removed, + deleted ON post + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_post_count (); + +CREATE TRIGGER community_aggregates_comment_count + AFTER INSERT OR DELETE OR UPDATE OF removed, + deleted ON comment + FOR EACH ROW + EXECUTE PROCEDURE community_aggregates_comment_count (); -create trigger site_aggregates_post_insert - after insert or update of removed, deleted on post - for each row - when (NEW.local = true) -execute procedure site_aggregates_post_insert(); - -create trigger site_aggregates_post_delete - after delete or update of removed, deleted on post - for each row - when (OLD.local = true) -execute procedure site_aggregates_post_delete(); - -create trigger site_aggregates_comment_insert - after insert or update of removed, deleted on comment - for each row - when (NEW.local = true) -execute procedure site_aggregates_comment_insert(); - -create trigger site_aggregates_comment_delete - after delete or update of removed, deleted on comment - for each row - when (OLD.local = true) -execute procedure site_aggregates_comment_delete(); - -create trigger site_aggregates_community_insert - after insert or update of removed, deleted on community - for each row - when (NEW.local = true) -execute procedure site_aggregates_community_insert(); - -create trigger site_aggregates_community_delete - after delete or update of removed, deleted on community - for each row - when (OLD.local = true) -execute procedure site_aggregates_community_delete(); +-- Site aggregate functions +CREATE OR REPLACE FUNCTION site_aggregates_post_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + posts = posts + 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; --- Person aggregate functions +CREATE OR REPLACE FUNCTION site_aggregates_post_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + posts = posts - 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; -create or replace function person_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count + 1 where person_id = NEW.creator_id; +CREATE OR REPLACE FUNCTION site_aggregates_comment_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + comments = comments + 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count - 1 where person_id = OLD.creator_id; +CREATE OR REPLACE FUNCTION site_aggregates_comment_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + comments = comments - 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; +CREATE OR REPLACE FUNCTION site_aggregates_community_insert () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + communities = communities + 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; + +CREATE OR REPLACE FUNCTION site_aggregates_community_delete () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + site_aggregates sa + SET + communities = communities - 1 + FROM + site s + WHERE + sa.site_id = s.id; + END IF; + RETURN NULL; +END +$$; + +-- Site aggregate triggers +CREATE TRIGGER site_aggregates_post_insert + AFTER INSERT OR UPDATE OF removed, + deleted ON post + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_insert (); + +CREATE TRIGGER site_aggregates_post_delete + AFTER DELETE OR UPDATE OF removed, + deleted ON post + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_post_delete (); + +CREATE TRIGGER site_aggregates_comment_insert + AFTER INSERT OR UPDATE OF removed, + deleted ON comment + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_insert (); + +CREATE TRIGGER site_aggregates_comment_delete + AFTER DELETE OR UPDATE OF removed, + deleted ON comment + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_comment_delete (); + +CREATE TRIGGER site_aggregates_community_insert + AFTER INSERT OR UPDATE OF removed, + deleted ON community + FOR EACH ROW + WHEN (NEW.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_insert (); + +CREATE TRIGGER site_aggregates_community_delete + AFTER DELETE OR UPDATE OF removed, + deleted ON community + FOR EACH ROW + WHEN (OLD.local = TRUE) + EXECUTE PROCEDURE site_aggregates_community_delete (); + +-- Person aggregate functions +CREATE OR REPLACE FUNCTION person_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + post_count = post_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) 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 and p.deleted = 'f' and p.removed = 'f' - left join post_like pl on p.id = pl.post_id - group by u.id - ) pd - where ua.person_id = OLD.creator_id; - + 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 + AND p.deleted = 'f' + AND p.removed = 'f' + 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 or replace function person_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count + 1 where person_id = NEW.creator_id; - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count - 1 where person_id = OLD.creator_id; + RETURN NULL; +END +$$; +CREATE OR REPLACE FUNCTION person_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + comment_count = comment_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) 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 and c.deleted = 'f' and c.removed = 'f' - left join comment_like cl on c.id = cl.comment_id - group by u.id - ) cd - where ua.person_id = OLD.creator_id; + 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 + AND c.deleted = 'f' + AND c.removed = 'f' + 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 $$; + RETURN NULL; +END +$$; -- Person aggregate triggers +CREATE TRIGGER person_aggregates_post_count + AFTER INSERT OR DELETE OR UPDATE OF removed, + deleted ON post + FOR EACH ROW + EXECUTE PROCEDURE person_aggregates_post_count (); + +CREATE TRIGGER person_aggregates_comment_count + AFTER INSERT OR DELETE OR UPDATE OF removed, + deleted ON comment + FOR EACH ROW + EXECUTE PROCEDURE person_aggregates_comment_count (); -create trigger person_aggregates_post_count - after insert or delete or update of removed, deleted on post - for each row -execute procedure person_aggregates_post_count(); - -create trigger person_aggregates_comment_count - after insert or delete or update of removed, deleted on comment - for each row -execute procedure person_aggregates_comment_count(); diff --git a/migrations/2022-04-11-210137_fix_unique_changeme/down.sql b/migrations/2022-04-11-210137_fix_unique_changeme/down.sql index 28198e89..00aa1c71 100644 --- a/migrations/2022-04-11-210137_fix_unique_changeme/down.sql +++ b/migrations/2022-04-11-210137_fix_unique_changeme/down.sql @@ -1,6 +1,10 @@ -create or replace function generate_unique_changeme() -returns text language sql -as $$ - select 'http://changeme_' || string_agg (substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil (random() * 62)::integer, 1), '') - from generate_series(1, 20) +CREATE OR REPLACE FUNCTION generate_unique_changeme () + RETURNS text + LANGUAGE sql + AS $$ + SELECT + 'http://changeme_' || string_agg(substr('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789', ceil(random() * 62)::integer, 1), '') + FROM + generate_series(1, 20) $$; + diff --git a/migrations/2022-04-11-210137_fix_unique_changeme/up.sql b/migrations/2022-04-11-210137_fix_unique_changeme/up.sql index 46fe55b5..5cd927d2 100644 --- a/migrations/2022-04-11-210137_fix_unique_changeme/up.sql +++ b/migrations/2022-04-11-210137_fix_unique_changeme/up.sql @@ -1,5 +1,8 @@ -create or replace function generate_unique_changeme() -returns text language sql -as $$ - select 'http://changeme.invalid/' || substr(md5(random()::text), 0, 25); +CREATE OR REPLACE FUNCTION generate_unique_changeme () + RETURNS text + LANGUAGE sql + AS $$ + SELECT + 'http://changeme.invalid/' || substr(md5(random()::text), 0, 25); $$; + diff --git a/migrations/2022-04-12-114352_default_post_listing_type/down.sql b/migrations/2022-04-12-114352_default_post_listing_type/down.sql index b70a7dd0..9d51d7ca 100644 --- a/migrations/2022-04-12-114352_default_post_listing_type/down.sql +++ b/migrations/2022-04-12-114352_default_post_listing_type/down.sql @@ -1 +1,3 @@ -alter table site drop column default_post_listing_type; +ALTER TABLE site + DROP COLUMN default_post_listing_type; + diff --git a/migrations/2022-04-12-114352_default_post_listing_type/up.sql b/migrations/2022-04-12-114352_default_post_listing_type/up.sql index f68e198f..7cd0602e 100644 --- a/migrations/2022-04-12-114352_default_post_listing_type/up.sql +++ b/migrations/2022-04-12-114352_default_post_listing_type/up.sql @@ -1 +1,3 @@ -alter table site add column default_post_listing_type text not null default 'Local'; +ALTER TABLE site + ADD COLUMN default_post_listing_type text NOT NULL DEFAULT 'Local'; + diff --git a/migrations/2022-04-12-185205_change_default_listing_type_to_local/down.sql b/migrations/2022-04-12-185205_change_default_listing_type_to_local/down.sql index d1d35659..573677a9 100644 --- a/migrations/2022-04-12-185205_change_default_listing_type_to_local/down.sql +++ b/migrations/2022-04-12-185205_change_default_listing_type_to_local/down.sql @@ -1,3 +1,4 @@ -- 0 is All, 1 is Local, 2 is Subscribed +ALTER TABLE ONLY local_user + ALTER COLUMN default_listing_type SET DEFAULT 2; -alter table only local_user alter column default_listing_type set default 2; diff --git a/migrations/2022-04-12-185205_change_default_listing_type_to_local/up.sql b/migrations/2022-04-12-185205_change_default_listing_type_to_local/up.sql index 15f0509e..a0054a26 100644 --- a/migrations/2022-04-12-185205_change_default_listing_type_to_local/up.sql +++ b/migrations/2022-04-12-185205_change_default_listing_type_to_local/up.sql @@ -1,3 +1,4 @@ -- 0 is All, 1 is Local, 2 is Subscribed +ALTER TABLE ONLY local_user + ALTER COLUMN default_listing_type SET DEFAULT 1; -alter table only local_user alter column default_listing_type set default 1; diff --git a/migrations/2022-04-19-111004_default_require_application/down.sql b/migrations/2022-04-19-111004_default_require_application/down.sql index eaa29a3c..1fb99348 100644 --- a/migrations/2022-04-19-111004_default_require_application/down.sql +++ b/migrations/2022-04-19-111004_default_require_application/down.sql @@ -1,2 +1,6 @@ -alter table site alter column require_application set default false; -alter table site alter column application_question set default null; \ No newline at end of file +ALTER TABLE site + ALTER COLUMN require_application SET DEFAULT FALSE; + +ALTER TABLE site + ALTER COLUMN application_question SET DEFAULT NULL; + diff --git a/migrations/2022-04-19-111004_default_require_application/up.sql b/migrations/2022-04-19-111004_default_require_application/up.sql index 1e326f17..35722288 100644 --- a/migrations/2022-04-19-111004_default_require_application/up.sql +++ b/migrations/2022-04-19-111004_default_require_application/up.sql @@ -1,2 +1,6 @@ -alter table site alter column require_application set default true; -alter table site alter column application_question set default 'To verify that you are human, please explain why you want to create an account on this site'; \ No newline at end of file +ALTER TABLE site + ALTER COLUMN require_application SET DEFAULT TRUE; + +ALTER TABLE site + ALTER COLUMN application_question SET DEFAULT 'To verify that you are human, please explain why you want to create an account on this site'; + diff --git a/migrations/2022-04-26-105145_only_mod_can_post/down.sql b/migrations/2022-04-26-105145_only_mod_can_post/down.sql index a9c95bf6..c74fe40c 100644 --- a/migrations/2022-04-26-105145_only_mod_can_post/down.sql +++ b/migrations/2022-04-26-105145_only_mod_can_post/down.sql @@ -1 +1,3 @@ -alter table community drop column posting_restricted_to_mods; \ No newline at end of file +ALTER TABLE community + DROP COLUMN posting_restricted_to_mods; + diff --git a/migrations/2022-04-26-105145_only_mod_can_post/up.sql b/migrations/2022-04-26-105145_only_mod_can_post/up.sql index fbc56983..176de3cb 100644 --- a/migrations/2022-04-26-105145_only_mod_can_post/up.sql +++ b/migrations/2022-04-26-105145_only_mod_can_post/up.sql @@ -1 +1,3 @@ -alter table community add column posting_restricted_to_mods boolean default false; \ No newline at end of file +ALTER TABLE community + ADD COLUMN posting_restricted_to_mods boolean DEFAULT FALSE; + diff --git a/migrations/2022-05-19-153931_legal-information/down.sql b/migrations/2022-05-19-153931_legal-information/down.sql index 0df8c19e..f8a398e6 100644 --- a/migrations/2022-05-19-153931_legal-information/down.sql +++ b/migrations/2022-05-19-153931_legal-information/down.sql @@ -1 +1,3 @@ -alter table site drop column legal_information; \ No newline at end of file +ALTER TABLE site + DROP COLUMN legal_information; + diff --git a/migrations/2022-05-19-153931_legal-information/up.sql b/migrations/2022-05-19-153931_legal-information/up.sql index 641fe63f..01266d0f 100644 --- a/migrations/2022-05-19-153931_legal-information/up.sql +++ b/migrations/2022-05-19-153931_legal-information/up.sql @@ -1 +1,3 @@ -alter table site add column legal_information text; \ No newline at end of file +ALTER TABLE site + ADD COLUMN legal_information text; + diff --git a/migrations/2022-05-20-135341_embed-url/down.sql b/migrations/2022-05-20-135341_embed-url/down.sql index 1c4ff1f6..4ce7051a 100644 --- a/migrations/2022-05-20-135341_embed-url/down.sql +++ b/migrations/2022-05-20-135341_embed-url/down.sql @@ -1,2 +1,6 @@ -alter table post drop column embed_url; -alter table post add column embed_video_url text; \ No newline at end of file +ALTER TABLE post + DROP COLUMN embed_url; + +ALTER TABLE post + ADD COLUMN embed_video_url text; + diff --git a/migrations/2022-05-20-135341_embed-url/up.sql b/migrations/2022-05-20-135341_embed-url/up.sql index 47d0df68..d69c0f31 100644 --- a/migrations/2022-05-20-135341_embed-url/up.sql +++ b/migrations/2022-05-20-135341_embed-url/up.sql @@ -1,2 +1,6 @@ -alter table post drop column embed_html; -alter table post add column embed_video_url text; \ No newline at end of file +ALTER TABLE post + DROP COLUMN embed_html; + +ALTER TABLE post + ADD COLUMN embed_video_url text; + diff --git a/migrations/2022-06-12-012121_add_site_hide_modlog_names/down.sql b/migrations/2022-06-12-012121_add_site_hide_modlog_names/down.sql index c3f65817..d758752d 100644 --- a/migrations/2022-06-12-012121_add_site_hide_modlog_names/down.sql +++ b/migrations/2022-06-12-012121_add_site_hide_modlog_names/down.sql @@ -1 +1,3 @@ -alter table site drop column hide_modlog_mod_names; \ No newline at end of file +ALTER TABLE site + DROP COLUMN hide_modlog_mod_names; + diff --git a/migrations/2022-06-12-012121_add_site_hide_modlog_names/up.sql b/migrations/2022-06-12-012121_add_site_hide_modlog_names/up.sql index 329ad6f4..bb8e6564 100644 --- a/migrations/2022-06-12-012121_add_site_hide_modlog_names/up.sql +++ b/migrations/2022-06-12-012121_add_site_hide_modlog_names/up.sql @@ -1 +1,3 @@ -alter table site add column hide_modlog_mod_names boolean default true NOT NULL; \ No newline at end of file +ALTER TABLE site + ADD COLUMN hide_modlog_mod_names boolean DEFAULT TRUE NOT NULL; + diff --git a/migrations/2022-06-13-124806_post_report_name_length/down.sql b/migrations/2022-06-13-124806_post_report_name_length/down.sql index f7b3a95e..7f99a59c 100644 --- a/migrations/2022-06-13-124806_post_report_name_length/down.sql +++ b/migrations/2022-06-13-124806_post_report_name_length/down.sql @@ -1 +1,3 @@ -alter table post_report alter column original_post_name type varchar(100); +ALTER TABLE post_report + ALTER COLUMN original_post_name TYPE varchar(100); + diff --git a/migrations/2022-06-13-124806_post_report_name_length/up.sql b/migrations/2022-06-13-124806_post_report_name_length/up.sql index 76631151..595b1337 100644 --- a/migrations/2022-06-13-124806_post_report_name_length/up.sql +++ b/migrations/2022-06-13-124806_post_report_name_length/up.sql @@ -1,2 +1,4 @@ -- adjust length limit to match post.name -alter table post_report alter column original_post_name type varchar(200); +ALTER TABLE post_report + ALTER COLUMN original_post_name TYPE varchar(200); + diff --git a/migrations/2022-06-21-123144_language-tags/down.sql b/migrations/2022-06-21-123144_language-tags/down.sql index 22ce261f..8af971d0 100644 --- a/migrations/2022-06-21-123144_language-tags/down.sql +++ b/migrations/2022-06-21-123144_language-tags/down.sql @@ -1,6 +1,9 @@ -alter table post drop column language_id; -drop table local_user_language; -drop table language; +ALTER TABLE post + DROP COLUMN language_id; -alter table local_user rename column interface_language to lang; +DROP TABLE local_user_language; + +DROP TABLE LANGUAGE; + +ALTER TABLE local_user RENAME COLUMN interface_language TO lang; diff --git a/migrations/2022-06-21-123144_language-tags/up.sql b/migrations/2022-06-21-123144_language-tags/up.sql index e670a59d..9deb6b47 100644 --- a/migrations/2022-06-21-123144_language-tags/up.sql +++ b/migrations/2022-06-21-123144_language-tags/up.sql @@ -1,199 +1,758 @@ -create table language ( - id serial primary key, - code varchar(3), - name text +CREATE TABLE +LANGUAGE ( + id serial PRIMARY KEY, + code varchar(3), + name text ); -create table local_user_language ( - id serial primary key, - local_user_id int references local_user on update cascade on delete cascade not null, - language_id int references language on update cascade on delete cascade not null, - unique (local_user_id, language_id) + +CREATE TABLE local_user_language ( + id serial PRIMARY KEY, + local_user_id int REFERENCES local_user ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + language_id int REFERENCES + LANGUAGE ON + UPDATE CASCADE ON DELETE CASCADE NOT NULL, + UNIQUE (local_user_id, language_id) ); -alter table local_user rename column lang to interface_language; - -insert into language(id, code, name) values (0, 'und', 'Undetermined'); -alter table post add column language_id integer references language not null default 0; -insert into language(code, name) values ('aa', 'Afaraf'); -insert into language(code, name) values ('ab', 'аҧÑÑа бÑзÑÓа'); -insert into language(code, name) values ('ae', 'avesta'); -insert into language(code, name) values ('af', 'Afrikaans'); -insert into language(code, name) values ('ak', 'Akan'); -insert into language(code, name) values ('am', 'á ááá'); -insert into language(code, name) values ('an', 'aragonés'); -insert into language(code, name) values ('ar', 'اÙÙÙعÙرÙبÙÙÙÙØ©Ù'); -insert into language(code, name) values ('as', 'ঠসমà§à¦¯à¦¼à¦¾'); -insert into language(code, name) values ('av', 'Ð°Ð²Ð°Ñ Ð¼Ð°ÑÓ'); -insert into language(code, name) values ('ay', 'aymar aru'); -insert into language(code, name) values ('az', 'azÉrbaycan dili'); -insert into language(code, name) values ('ba', 'баÑҡоÑÑ Ñеле'); -insert into language(code, name) values ('be', 'белаÑÑÑÐºÐ°Ñ Ð¼Ð¾Ð²Ð°'); -insert into language(code, name) values ('bg', 'бÑлгаÑÑки език'); -insert into language(code, name) values ('bi', 'Bislama'); -insert into language(code, name) values ('bm', 'bamanankan'); -insert into language(code, name) values ('bn', 'বাà¦à¦²à¦¾'); -insert into language(code, name) values ('bo', 'à½à½¼à½à¼à½¡à½²à½'); -insert into language(code, name) values ('br', 'brezhoneg'); -insert into language(code, name) values ('bs', 'bosanski jezik'); -insert into language(code, name) values ('ca', 'Català '); -insert into language(code, name) values ('ce', 'Ð½Ð¾Ñ Ñийн моÑÑ'); -insert into language(code, name) values ('ch', 'Chamoru'); -insert into language(code, name) values ('co', 'corsu'); -insert into language(code, name) values ('cr', 'áá¦ááááá£'); -insert into language(code, name) values ('cs', 'ÄeÅ¡tina'); -insert into language(code, name) values ('cu', 'ѩзÑÐºÑ ÑловѣнÑÑкÑ'); -insert into language(code, name) values ('cv', 'ÑÓÐ²Ð°Ñ ÑÓÐ»Ñ Ð¸'); -insert into language(code, name) values ('cy', 'Cymraeg'); -insert into language(code, name) values ('da', 'dansk'); -insert into language(code, name) values ('de', 'Deutsch'); -insert into language(code, name) values ('dv', 'ÞÞ¨ÞÞ¬ÞÞ¨'); -insert into language(code, name) values ('dz', 'རྫོà½à¼à½'); -insert into language(code, name) values ('ee', 'EÊegbe'); -insert into language(code, name) values ('el', 'Îλληνικά'); -insert into language(code, name) values ('en', 'English'); -insert into language(code, name) values ('eo', 'Esperanto'); -insert into language(code, name) values ('es', 'Español'); -insert into language(code, name) values ('et', 'eesti'); -insert into language(code, name) values ('eu', 'euskara'); -insert into language(code, name) values ('fa', 'ÙارسÛ'); -insert into language(code, name) values ('ff', 'Fulfulde'); -insert into language(code, name) values ('fi', 'suomi'); -insert into language(code, name) values ('fj', 'vosa Vakaviti'); -insert into language(code, name) values ('fo', 'føroyskt'); -insert into language(code, name) values ('fr', 'Français'); -insert into language(code, name) values ('fy', 'Frysk'); -insert into language(code, name) values ('ga', 'Gaeilge'); -insert into language(code, name) values ('gd', 'Gà idhlig'); -insert into language(code, name) values ('gl', 'galego'); -insert into language(code, name) values ('gn', E'Avañe\'ẽ'); -insert into language(code, name) values ('gu', 'àªà«àªàª°àª¾àª¤à«'); -insert into language(code, name) values ('gv', 'Gaelg'); -insert into language(code, name) values ('ha', 'ÙÙÙÙسÙ'); -insert into language(code, name) values ('he', '×¢×ר×ת'); -insert into language(code, name) values ('hi', 'हिनà¥à¤¦à¥'); -insert into language(code, name) values ('ho', 'Hiri Motu'); -insert into language(code, name) values ('hr', 'Hrvatski'); -insert into language(code, name) values ('ht', 'Kreyòl ayisyen'); -insert into language(code, name) values ('hu', 'magyar'); -insert into language(code, name) values ('hy', 'ÕÕ¡ÕµÕ¥ÖÕ¥Õ¶'); -insert into language(code, name) values ('hz', 'Otjiherero'); -insert into language(code, name) values ('ia', 'Interlingua'); -insert into language(code, name) values ('id', 'Bahasa Indonesia'); -insert into language(code, name) values ('ie', 'Interlingue'); -insert into language(code, name) values ('ig', 'Asụsụ Igbo'); -insert into language(code, name) values ('ii', 'êê ê¿ Nuosuhxop'); -insert into language(code, name) values ('ik', 'Iñupiaq'); -insert into language(code, name) values ('io', 'Ido'); -insert into language(code, name) values ('is', 'Ãslenska'); -insert into language(code, name) values ('it', 'Italiano'); -insert into language(code, name) values ('iu', 'áááááá¦'); -insert into language(code, name) values ('ja', 'æ¥æ¬èª'); -insert into language(code, name) values ('jv', 'basa Jawa'); -insert into language(code, name) values ('ka', 'á¥áá áá£áá'); -insert into language(code, name) values ('kg', 'Kikongo'); -insert into language(code, name) values ('ki', 'GÄ©kÅ©yÅ©'); -insert into language(code, name) values ('kj', 'Kuanyama'); -insert into language(code, name) values ('kk', 'ÒÐ°Ð·Ð°Ò ÑÑлÑ'); -insert into language(code, name) values ('kl', 'kalaallisut'); -insert into language(code, name) values ('km', 'áááááá¶áá¶'); -insert into language(code, name) values ('kn', 'à²à²¨à³à²¨à²¡'); -insert into language(code, name) values ('ko', 'íêµì´'); -insert into language(code, name) values ('kr', 'Kanuri'); -insert into language(code, name) values ('ks', 'à¤à¤¶à¥à¤®à¥à¤°à¥'); -insert into language(code, name) values ('ku', 'Kurdî'); -insert into language(code, name) values ('kv', 'коми кÑв'); -insert into language(code, name) values ('kw', 'Kernewek'); -insert into language(code, name) values ('ky', 'ÐÑÑгÑзÑа'); -insert into language(code, name) values ('la', 'latine'); -insert into language(code, name) values ('lb', 'Lëtzebuergesch'); -insert into language(code, name) values ('lg', 'Luganda'); -insert into language(code, name) values ('li', 'Limburgs'); -insert into language(code, name) values ('ln', 'Lingála'); -insert into language(code, name) values ('lo', 'àºàº²àºªàº²àº¥àº²àº§'); -insert into language(code, name) values ('lt', 'lietuvių kalba'); -insert into language(code, name) values ('lu', 'Kiluba'); -insert into language(code, name) values ('lv', 'latvieÅ¡u valoda'); -insert into language(code, name) values ('mg', 'fiteny malagasy'); -insert into language(code, name) values ('mh', 'Kajin M̧ajeļ'); -insert into language(code, name) values ('mi', 'te reo MÄori'); -insert into language(code, name) values ('mk', 'македонÑки Ñазик'); -insert into language(code, name) values ('ml', 'മലയാളà´'); -insert into language(code, name) values ('mn', 'Ðонгол Ñ Ñл'); -insert into language(code, name) values ('mr', 'मराठà¥'); -insert into language(code, name) values ('ms', 'Bahasa Melayu'); -insert into language(code, name) values ('mt', 'Malti'); -insert into language(code, name) values ('my', 'ááá¬á á¬'); -insert into language(code, name) values ('na', 'Dorerin Naoero'); -insert into language(code, name) values ('nb', 'Norsk bokmÃ¥l'); -insert into language(code, name) values ('nd', 'isiNdebele'); -insert into language(code, name) values ('ne', 'नà¥à¤ªà¤¾à¤²à¥'); -insert into language(code, name) values ('ng', 'Owambo'); -insert into language(code, name) values ('nl', 'Nederlands'); -insert into language(code, name) values ('nn', 'Norsk nynorsk'); -insert into language(code, name) values ('no', 'Norsk'); -insert into language(code, name) values ('nr', 'isiNdebele'); -insert into language(code, name) values ('nv', 'Diné bizaad'); -insert into language(code, name) values ('ny', 'chiCheŵa'); -insert into language(code, name) values ('oc', 'occitan'); -insert into language(code, name) values ('oj', 'ááááá¯á§áá'); -insert into language(code, name) values ('om', 'Afaan Oromoo'); -insert into language(code, name) values ('or', 'à¬à¬¡à¬¼à¬¿à¬'); -insert into language(code, name) values ('os', 'иÑон æвзаг'); -insert into language(code, name) values ('pa', 'ਪੰà¨à¨¾à¨¬à©'); -insert into language(code, name) values ('pi', 'पाऴि'); -insert into language(code, name) values ('pl', 'Polski'); -insert into language(code, name) values ('ps', 'Ù¾ÚتÙ'); -insert into language(code, name) values ('pt', 'Português'); -insert into language(code, name) values ('qu', 'Runa Simi'); -insert into language(code, name) values ('rm', 'rumantsch grischun'); -insert into language(code, name) values ('rn', 'Ikirundi'); -insert into language(code, name) values ('ro', 'RomânÄ'); -insert into language(code, name) values ('ru', 'Ð ÑÑÑкий'); -insert into language(code, name) values ('rw', 'Ikinyarwanda'); -insert into language(code, name) values ('sa', 'सà¤à¤¸à¥à¤à¥à¤¤à¤®à¥'); -insert into language(code, name) values ('sc', 'sardu'); -insert into language(code, name) values ('sd', 'सिनà¥à¤§à¥'); -insert into language(code, name) values ('se', 'Davvisámegiella'); -insert into language(code, name) values ('sg', 'yângâ tî sängö'); -insert into language(code, name) values ('si', 'à·à·à¶à·à¶½'); -insert into language(code, name) values ('sk', 'slovenÄina'); -insert into language(code, name) values ('sl', 'slovenÅ¡Äina'); -insert into language(code, name) values ('sm', E'gagana fa\'a Samoa'); -insert into language(code, name) values ('sn', 'chiShona'); -insert into language(code, name) values ('so', 'Soomaaliga'); -insert into language(code, name) values ('sq', 'Shqip'); -insert into language(code, name) values ('sr', 'ÑÑпÑки Ñезик'); -insert into language(code, name) values ('ss', 'SiSwati'); -insert into language(code, name) values ('st', 'Sesotho'); -insert into language(code, name) values ('su', 'Basa Sunda'); -insert into language(code, name) values ('sv', 'Svenska'); -insert into language(code, name) values ('sw', 'Kiswahili'); -insert into language(code, name) values ('ta', 'தமிழà¯'); -insert into language(code, name) values ('te', 'à°¤à±à°²à±à°à±'); -insert into language(code, name) values ('tg', 'Ñоҷикӣ'); -insert into language(code, name) values ('th', 'à¹à¸à¸¢'); -insert into language(code, name) values ('ti', 'áµááá'); -insert into language(code, name) values ('tk', 'Türkmençe'); -insert into language(code, name) values ('tl', 'Wikang Tagalog'); -insert into language(code, name) values ('tn', 'Setswana'); -insert into language(code, name) values ('to', 'faka Tonga'); -insert into language(code, name) values ('tr', 'Türkçe'); -insert into language(code, name) values ('ts', 'Xitsonga'); -insert into language(code, name) values ('tt', 'ÑаÑÐ°Ñ Ñеле'); -insert into language(code, name) values ('tw', 'Twi'); -insert into language(code, name) values ('ty', 'Reo Tahiti'); -insert into language(code, name) values ('ug', 'ئÛÙغÛرÚÛâ'); -insert into language(code, name) values ('uk', 'УкÑаÑнÑÑка'); -insert into language(code, name) values ('ur', 'اردÙ'); -insert into language(code, name) values ('uz', 'Ðзбек'); -insert into language(code, name) values ('ve', 'Tshivená¸a'); -insert into language(code, name) values ('vi', 'Tiếng Viá»t'); -insert into language(code, name) values ('vo', 'Volapük'); -insert into language(code, name) values ('wa', 'walon'); -insert into language(code, name) values ('wo', 'Wollof'); -insert into language(code, name) values ('xh', 'isiXhosa'); -insert into language(code, name) values ('yi', '××Ö´××ש'); -insert into language(code, name) values ('yo', 'Yorùbá'); -insert into language(code, name) values ('za', 'Saɯ cueÅÆ '); -insert into language(code, name) values ('zh', 'ä¸æ'); -insert into language(code, name) values ('zu', 'isiZulu'); +ALTER TABLE local_user RENAME COLUMN lang TO interface_language; + +INSERT INTO +LANGUAGE (id, code, name) + VALUES (0, 'und', 'Undetermined'); + +ALTER TABLE post + ADD COLUMN language_id integer REFERENCES LANGUAGE NOT + NULL DEFAULT 0; + +INSERT INTO +LANGUAGE (code, name) + VALUES ('aa', 'Afaraf'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ab', 'аҧÑÑа бÑзÑÓа'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ae', 'avesta'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('af', 'Afrikaans'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ak', 'Akan'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('am', 'á ááá'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('an', 'aragonés'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ar', 'اÙÙÙعÙرÙبÙÙÙÙØ©Ù'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('as', 'ঠসমà§à¦¯à¦¼à¦¾'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('av', 'Ð°Ð²Ð°Ñ Ð¼Ð°ÑÓ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ay', 'aymar aru'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('az', 'azÉrbaycan dili'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ba', 'баÑҡоÑÑ Ñеле'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('be', 'белаÑÑÑÐºÐ°Ñ Ð¼Ð¾Ð²Ð°'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bg', 'бÑлгаÑÑки език'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bi', 'Bislama'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bm', 'bamanankan'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bn', 'বাà¦à¦²à¦¾'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bo', 'à½à½¼à½à¼à½¡à½²à½'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('br', 'brezhoneg'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('bs', 'bosanski jezik'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ca', 'Català '); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ce', 'Ð½Ð¾Ñ Ñийн моÑÑ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ch', 'Chamoru'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('co', 'corsu'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('cr', 'áá¦ááááá£'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('cs', 'ÄeÅ¡tina'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('cu', 'ѩзÑÐºÑ ÑловѣнÑÑкÑ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('cv', 'ÑÓÐ²Ð°Ñ ÑÓÐ»Ñ Ð¸'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('cy', 'Cymraeg'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('da', 'dansk'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('de', 'Deutsch'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('dv', 'ÞÞ¨ÞÞ¬ÞÞ¨'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('dz', 'རྫོà½à¼à½'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ee', 'EÊegbe'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('el', 'Îλληνικά'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('en', 'English'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('eo', 'Esperanto'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('es', 'Español'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('et', 'eesti'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('eu', 'euskara'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fa', 'ÙارسÛ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ff', 'Fulfulde'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fi', 'suomi'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fj', 'vosa Vakaviti'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fo', 'føroyskt'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fr', 'Français'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('fy', 'Frysk'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ga', 'Gaeilge'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('gd', 'Gà idhlig'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('gl', 'galego'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('gn', E'Avañe\'ẽ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('gu', 'àªà«àªàª°àª¾àª¤à«'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('gv', 'Gaelg'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ha', 'ÙÙÙÙسÙ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('he', '×¢×ר×ת'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('hi', 'हिनà¥à¤¦à¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ho', 'Hiri Motu'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('hr', 'Hrvatski'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ht', 'Kreyòl ayisyen'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('hu', 'magyar'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('hy', 'ÕÕ¡ÕµÕ¥ÖÕ¥Õ¶'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('hz', 'Otjiherero'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ia', 'Interlingua'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('id', 'Bahasa Indonesia'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ie', 'Interlingue'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ig', 'Asụsụ Igbo'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ii', 'êê ê¿ Nuosuhxop'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ik', 'Iñupiaq'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('io', 'Ido'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('is', 'Ãslenska'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('it', 'Italiano'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('iu', 'áááááá¦'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ja', 'æ¥æ¬èª'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('jv', 'basa Jawa'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ka', 'á¥áá áá£áá'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kg', 'Kikongo'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ki', 'GÄ©kÅ©yÅ©'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kj', 'Kuanyama'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kk', 'ÒÐ°Ð·Ð°Ò ÑÑлÑ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kl', 'kalaallisut'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('km', 'áááááá¶áá¶'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kn', 'à²à²¨à³à²¨à²¡'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ko', 'íêµì´'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kr', 'Kanuri'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ks', 'à¤à¤¶à¥à¤®à¥à¤°à¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ku', 'Kurdî'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kv', 'коми кÑв'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('kw', 'Kernewek'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ky', 'ÐÑÑгÑзÑа'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('la', 'latine'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lb', 'Lëtzebuergesch'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lg', 'Luganda'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('li', 'Limburgs'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ln', 'Lingála'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lo', 'àºàº²àºªàº²àº¥àº²àº§'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lt', 'lietuvių kalba'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lu', 'Kiluba'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('lv', 'latvieÅ¡u valoda'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mg', 'fiteny malagasy'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mh', 'Kajin M̧ajeļ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mi', 'te reo MÄori'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mk', 'македонÑки Ñазик'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ml', 'മലയാളà´'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mn', 'Ðонгол Ñ Ñл'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mr', 'मराठà¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ms', 'Bahasa Melayu'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('mt', 'Malti'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('my', 'ááá¬á á¬'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('na', 'Dorerin Naoero'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nb', 'Norsk bokmÃ¥l'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nd', 'isiNdebele'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ne', 'नà¥à¤ªà¤¾à¤²à¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ng', 'Owambo'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nl', 'Nederlands'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nn', 'Norsk nynorsk'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('no', 'Norsk'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nr', 'isiNdebele'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('nv', 'Diné bizaad'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ny', 'chiCheŵa'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('oc', 'occitan'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('oj', 'ááááá¯á§áá'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('om', 'Afaan Oromoo'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('or', 'à¬à¬¡à¬¼à¬¿à¬'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('os', 'иÑон æвзаг'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('pa', 'ਪੰà¨à¨¾à¨¬à©'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('pi', 'पाऴि'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('pl', 'Polski'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ps', 'Ù¾ÚتÙ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('pt', 'Português'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('qu', 'Runa Simi'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('rm', 'rumantsch grischun'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('rn', 'Ikirundi'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ro', 'RomânÄ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ru', 'Ð ÑÑÑкий'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('rw', 'Ikinyarwanda'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sa', 'सà¤à¤¸à¥à¤à¥à¤¤à¤®à¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sc', 'sardu'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sd', 'सिनà¥à¤§à¥'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('se', 'Davvisámegiella'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sg', 'yângâ tî sängö'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('si', 'à·à·à¶à·à¶½'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sk', 'slovenÄina'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sl', 'slovenÅ¡Äina'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sm', E'gagana fa\'a Samoa'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sn', 'chiShona'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('so', 'Soomaaliga'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sq', 'Shqip'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sr', 'ÑÑпÑки Ñезик'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ss', 'SiSwati'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('st', 'Sesotho'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('su', 'Basa Sunda'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sv', 'Svenska'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('sw', 'Kiswahili'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ta', 'தமிழà¯'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('te', 'à°¤à±à°²à±à°à±'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tg', 'Ñоҷикӣ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('th', 'à¹à¸à¸¢'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ti', 'áµááá'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tk', 'Türkmençe'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tl', 'Wikang Tagalog'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tn', 'Setswana'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('to', 'faka Tonga'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tr', 'Türkçe'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ts', 'Xitsonga'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tt', 'ÑаÑÐ°Ñ Ñеле'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('tw', 'Twi'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ty', 'Reo Tahiti'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ug', 'ئÛÙغÛرÚÛâ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('uk', 'УкÑаÑнÑÑка'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ur', 'اردÙ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('uz', 'Ðзбек'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('ve', 'Tshivená¸a'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('vi', 'Tiếng Viá»t'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('vo', 'Volapük'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('wa', 'walon'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('wo', 'Wollof'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('xh', 'isiXhosa'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('yi', '××Ö´××ש'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('yo', 'Yorùbá'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('za', 'Saɯ cueÅÆ '); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('zh', 'ä¸æ'); + +INSERT INTO +LANGUAGE (code, name) + VALUES ('zu', 'isiZulu'); + diff --git a/migrations/2022-07-07-182650_comment_ltrees/down.sql b/migrations/2022-07-07-182650_comment_ltrees/down.sql index 6385f62c..fce2e139 100644 --- a/migrations/2022-07-07-182650_comment_ltrees/down.sql +++ b/migrations/2022-07-07-182650_comment_ltrees/down.sql @@ -1,25 +1,45 @@ -alter table comment add column parent_id integer; +ALTER TABLE comment + ADD COLUMN parent_id integer; -- Constraints and index -alter table comment add constraint comment_parent_id_fkey foreign key (parent_id) REFERENCES comment(id) ON UPDATE CASCADE ON DELETE CASCADE; -create index idx_comment_parent on comment (parent_id); +ALTER TABLE comment + ADD CONSTRAINT comment_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES comment (id) ON UPDATE CASCADE ON DELETE CASCADE; + +CREATE INDEX idx_comment_parent ON comment (parent_id); -- Update the parent_id column -- subpath(subpath(0, -1), -1) gets the immediate parent but it fails null checks -update comment set parent_id = cast(ltree2text(nullif(subpath(nullif(subpath(path, 0, -1), '0'), -1), '0')) as INTEGER); - -alter table comment drop column path; -alter table comment_aggregates drop column child_count; +UPDATE + comment +SET + parent_id = cast(ltree2text (nullif (subpath (nullif (subpath (path, 0, -1), '0'), -1), '0')) AS INTEGER); -drop extension ltree; +ALTER TABLE comment + DROP COLUMN path; --- Add back in the read column -alter table comment add column read boolean default false not null; +ALTER TABLE comment_aggregates + DROP COLUMN child_count; -update comment c set read = cr.read -from comment_reply cr where cr.comment_id = c.id; +DROP EXTENSION ltree; -create view comment_alias_1 as select * from comment; - -drop table comment_reply; +-- Add back in the read column +ALTER TABLE comment + ADD COLUMN read boolean DEFAULT FALSE NOT NULL; + +UPDATE + comment c +SET + read = cr.read +FROM + comment_reply cr +WHERE + cr.comment_id = c.id; + +CREATE VIEW comment_alias_1 AS +SELECT + * +FROM + comment; + +DROP TABLE comment_reply; diff --git a/migrations/2022-07-07-182650_comment_ltrees/up.sql b/migrations/2022-07-07-182650_comment_ltrees/up.sql index 4d2598dd..08c0141d 100644 --- a/migrations/2022-07-07-182650_comment_ltrees/up.sql +++ b/migrations/2022-07-07-182650_comment_ltrees/up.sql @@ -1,118 +1,184 @@ -- Remove the comment.read column, and create a new comment_reply table, --- similar to the person_mention table. --- +-- similar to the person_mention table. +-- -- This is necessary because self-joins using ltrees would be too tough with SQL views --- --- Every comment should have a row here, because all comments have a recipient, +-- +-- Every comment should have a row here, because all comments have a recipient, -- either the post creator, or the parent commenter. -create table comment_reply( - id serial primary key, - recipient_id int references person on update cascade on delete cascade not null, - comment_id int references comment on update cascade on delete cascade not null, - read boolean default false not null, - published timestamp not null default now(), - unique(recipient_id, comment_id) +CREATE TABLE comment_reply ( + id serial PRIMARY KEY, + recipient_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + comment_id int REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + read boolean DEFAULT FALSE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (recipient_id, comment_id) ); -- Ones where parent_id is null, use the post creator recipient -insert into comment_reply (recipient_id, comment_id, read) -select p.creator_id, c.id, c.read from comment c -inner join post p on c.post_id = p.id -where c.parent_id is null; +INSERT INTO comment_reply (recipient_id, comment_id, read) +SELECT + p.creator_id, + c.id, + c.read +FROM + comment c + INNER JOIN post p ON c.post_id = p.id +WHERE + c.parent_id IS NULL; -- Ones where there is a parent_id, self join to comment to get the parent comment creator -insert into comment_reply (recipient_id, comment_id, read) -select c2.creator_id, c.id, c.read from comment c -inner join comment c2 on c.parent_id = c2.id; +INSERT INTO comment_reply (recipient_id, comment_id, read) +SELECT + c2.creator_id, + c.id, + c.read +FROM + comment c + INNER JOIN comment c2 ON c.parent_id = c2.id; -- Drop comment_alias view -drop view comment_alias_1; +DROP VIEW comment_alias_1; -alter table comment drop column read; +ALTER TABLE comment + DROP COLUMN read; -create extension if not exists ltree; +CREATE EXTENSION IF NOT EXISTS ltree; -alter table comment add column path ltree not null default '0'; -alter table comment_aggregates add column child_count integer not null default 0; +ALTER TABLE comment + ADD COLUMN path ltree NOT NULL DEFAULT '0'; --- The ltree path column should be the comment_id parent paths, separated by dots. +ALTER TABLE comment_aggregates + ADD COLUMN child_count integer NOT NULL DEFAULT 0; + +-- The ltree path column should be the comment_id parent paths, separated by dots. -- Stackoverflow: building an ltree from a parent_id hierarchical tree: -- https://stackoverflow.com/a/1144848/1655478 - -create temporary table comment_temp as +CREATE TEMPORARY TABLE comment_temp AS WITH RECURSIVE q AS ( - SELECT h, 1 AS level, ARRAY[id] AS breadcrumb - FROM comment h - WHERE parent_id is null - UNION ALL - SELECT hi, q.level + 1 AS level, breadcrumb || id - FROM q - JOIN comment hi - ON hi.parent_id = (q.h).id + SELECT + h, + 1 AS level, + ARRAY[id] AS breadcrumb + FROM + comment h + WHERE + parent_id IS NULL + UNION ALL + SELECT + hi, + q.level + 1 AS level, + breadcrumb || id + FROM + q + JOIN comment hi ON hi.parent_id = (q.h).id ) -SELECT (q.h).id, - (q.h).parent_id, - level, - breadcrumb::VARCHAR AS path, - text2ltree('0.' || array_to_string(breadcrumb, '.')) as ltree_path -FROM q +SELECT + (q.h).id, + (q.h).parent_id, + level, + breadcrumb::varchar AS path, + text2ltree ('0.' || array_to_string(breadcrumb, '.')) AS ltree_path +FROM + q ORDER BY - breadcrumb; + breadcrumb; -- Remove indexes and foreign key constraints, and disable triggers for faster updates -alter table comment disable trigger user; +ALTER TABLE comment DISABLE TRIGGER USER; + +ALTER TABLE comment + DROP CONSTRAINT IF EXISTS comment_creator_id_fkey; + +ALTER TABLE comment + DROP CONSTRAINT IF EXISTS comment_parent_id_fkey; + +ALTER TABLE comment + DROP CONSTRAINT IF EXISTS comment_post_id_fkey; + +ALTER TABLE comment + DROP CONSTRAINT IF EXISTS idx_comment_ap_id; + +DROP INDEX IF EXISTS idx_comment_creator; + +DROP INDEX IF EXISTS idx_comment_parent; -alter table comment drop constraint if exists comment_creator_id_fkey; -alter table comment drop constraint if exists comment_parent_id_fkey; -alter table comment drop constraint if exists comment_post_id_fkey; -alter table comment drop constraint if exists idx_comment_ap_id; +DROP INDEX IF EXISTS idx_comment_post; -drop index if exists idx_comment_creator; -drop index if exists idx_comment_parent; -drop index if exists idx_comment_post; -drop index if exists idx_comment_published; +DROP INDEX IF EXISTS idx_comment_published; -- Add the ltree column -update comment c -set path = ct.ltree_path -from comment_temp ct -where c.id = ct.id; +UPDATE + comment c +SET + path = ct.ltree_path +FROM + comment_temp ct +WHERE + c.id = ct.id; -- Update the child counts -update comment_aggregates ca set child_count = c2.child_count -from ( - select c.id, c.path, count(c2.id) as child_count from comment c - left join comment c2 on c2.path <@ c.path and c2.path != c.path - group by c.id -) as c2 -where ca.comment_id = c2.id; +UPDATE + comment_aggregates ca +SET + child_count = c2.child_count +FROM ( + SELECT + c.id, + c.path, + count(c2.id) AS child_count + FROM + comment c + LEFT JOIN comment c2 ON c2.path <@ c.path + AND c2.path != c.path +GROUP BY + c.id) AS c2 +WHERE + ca.comment_id = c2.id; -- Delete comments at a depth of > 150, otherwise the index creation below will fail -delete from comment where nlevel(path) > 150; +DELETE FROM comment +WHERE nlevel (path) > 150; -- Delete from comment where there is a missing post -delete from comment c where not exists ( - select from post p where p.id = c.post_id -); +DELETE FROM comment c +WHERE NOT EXISTS ( + SELECT + FROM + post p + WHERE + p.id = c.post_id); -- Delete from comment where there is a missing creator_id -delete from comment c where not exists ( - select from person p where p.id = c.creator_id -); +DELETE FROM comment c +WHERE NOT EXISTS ( + SELECT + FROM + person p + WHERE + p.id = c.creator_id); -- Re-enable old constraints and indexes -alter table comment add constraint "comment_creator_id_fkey" FOREIGN KEY (creator_id) REFERENCES person(id) ON UPDATE CASCADE ON DELETE CASCADE; -alter table comment add constraint "comment_post_id_fkey" FOREIGN KEY (post_id) REFERENCES post(id) ON UPDATE CASCADE ON DELETE CASCADE; -alter table comment add constraint "idx_comment_ap_id" unique (ap_id); +ALTER TABLE comment + ADD CONSTRAINT "comment_creator_id_fkey" FOREIGN KEY (creator_id) REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE; + +ALTER TABLE comment + ADD CONSTRAINT "comment_post_id_fkey" FOREIGN KEY (post_id) REFERENCES post (id) ON UPDATE CASCADE ON DELETE CASCADE; + +ALTER TABLE comment + ADD CONSTRAINT "idx_comment_ap_id" UNIQUE (ap_id); -create index idx_comment_creator on comment (creator_id); -create index idx_comment_post on comment (post_id); -create index idx_comment_published on comment (published desc); +CREATE INDEX idx_comment_creator ON comment (creator_id); + +CREATE INDEX idx_comment_post ON comment (post_id); + +CREATE INDEX idx_comment_published ON comment (published DESC); -- Create the index -create index idx_path_gist on comment using gist (path); +CREATE INDEX idx_path_gist ON comment USING gist (path); -- Drop the parent_id column -alter table comment drop column parent_id cascade; +ALTER TABLE comment + DROP COLUMN parent_id CASCADE; + +ALTER TABLE comment ENABLE TRIGGER USER; -alter table comment enable trigger user; diff --git a/migrations/2022-08-04-150644_add_application_email_admins/down.sql b/migrations/2022-08-04-150644_add_application_email_admins/down.sql index c515275a..0f9228e9 100644 --- a/migrations/2022-08-04-150644_add_application_email_admins/down.sql +++ b/migrations/2022-08-04-150644_add_application_email_admins/down.sql @@ -1 +1,3 @@ -alter table site drop column application_email_admins; +ALTER TABLE site + DROP COLUMN application_email_admins; + diff --git a/migrations/2022-08-04-150644_add_application_email_admins/up.sql b/migrations/2022-08-04-150644_add_application_email_admins/up.sql index adf8f3c1..0bad5293 100644 --- a/migrations/2022-08-04-150644_add_application_email_admins/up.sql +++ b/migrations/2022-08-04-150644_add_application_email_admins/up.sql @@ -1,2 +1,4 @@ -- Adding a field to email admins for new applications -alter table site add column application_email_admins boolean not null default false; +ALTER TABLE site + ADD COLUMN application_email_admins boolean NOT NULL DEFAULT FALSE; + diff --git a/migrations/2022-08-04-214722_add_distinguished_comment/down.sql b/migrations/2022-08-04-214722_add_distinguished_comment/down.sql index fff64498..8af58692 100644 --- a/migrations/2022-08-04-214722_add_distinguished_comment/down.sql +++ b/migrations/2022-08-04-214722_add_distinguished_comment/down.sql @@ -1 +1,3 @@ -alter table comment drop column distinguished; +ALTER TABLE comment + DROP COLUMN distinguished; + diff --git a/migrations/2022-08-04-214722_add_distinguished_comment/up.sql b/migrations/2022-08-04-214722_add_distinguished_comment/up.sql index a23d2331..16f416ae 100644 --- a/migrations/2022-08-04-214722_add_distinguished_comment/up.sql +++ b/migrations/2022-08-04-214722_add_distinguished_comment/up.sql @@ -1 +1,3 @@ -alter table comment add column distinguished boolean not null default false; +ALTER TABLE comment + ADD COLUMN distinguished boolean NOT NULL DEFAULT FALSE; + diff --git a/migrations/2022-08-05-203502_add_person_post_aggregates/down.sql b/migrations/2022-08-05-203502_add_person_post_aggregates/down.sql index f4ae5263..e48e0a8d 100644 --- a/migrations/2022-08-05-203502_add_person_post_aggregates/down.sql +++ b/migrations/2022-08-05-203502_add_person_post_aggregates/down.sql @@ -1 +1,2 @@ -drop table person_post_aggregates; +DROP TABLE person_post_aggregates; + diff --git a/migrations/2022-08-05-203502_add_person_post_aggregates/up.sql b/migrations/2022-08-05-203502_add_person_post_aggregates/up.sql index 9a0a5fa5..4fcae3b2 100644 --- a/migrations/2022-08-05-203502_add_person_post_aggregates/up.sql +++ b/migrations/2022-08-05-203502_add_person_post_aggregates/up.sql @@ -1,11 +1,12 @@ -- This table stores the # of read comments for a person, on a post -- It can then be joined to post_aggregates to get an unread count: -- unread = post_aggregates.comments - person_post_aggregates.read_comments -create table person_post_aggregates( - id serial primary key, - person_id int references person on update cascade on delete cascade not null, - post_id int references post on update cascade on delete cascade not null, - read_comments bigint not null default 0, - published timestamp not null default now(), - unique(person_id, post_id) +CREATE TABLE person_post_aggregates ( + id serial PRIMARY KEY, + person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + read_comments bigint NOT NULL DEFAULT 0, + published timestamp NOT NULL DEFAULT now(), + UNIQUE (person_id, post_id) ); + diff --git a/migrations/2022-08-22-193848_comment-language-tags/down.sql b/migrations/2022-08-22-193848_comment-language-tags/down.sql index 7c15bfdc..745a6b35 100644 --- a/migrations/2022-08-22-193848_comment-language-tags/down.sql +++ b/migrations/2022-08-22-193848_comment-language-tags/down.sql @@ -1 +1,3 @@ -alter table comment drop column language_id; +ALTER TABLE comment + DROP COLUMN language_id; + diff --git a/migrations/2022-08-22-193848_comment-language-tags/up.sql b/migrations/2022-08-22-193848_comment-language-tags/up.sql index 78fe0e95..782931cb 100644 --- a/migrations/2022-08-22-193848_comment-language-tags/up.sql +++ b/migrations/2022-08-22-193848_comment-language-tags/up.sql @@ -1 +1,4 @@ -alter table comment add column language_id integer references language not null default 0; +ALTER TABLE comment + ADD COLUMN language_id integer REFERENCES LANGUAGE NOT + NULL DEFAULT 0; + diff --git a/migrations/2022-09-07-113813_drop_ccnew_indexes_function/down.sql b/migrations/2022-09-07-113813_drop_ccnew_indexes_function/down.sql index 3fc7778a..eede8186 100644 --- a/migrations/2022-09-07-113813_drop_ccnew_indexes_function/down.sql +++ b/migrations/2022-09-07-113813_drop_ccnew_indexes_function/down.sql @@ -1 +1,2 @@ -drop function drop_ccnew_indexes; +DROP FUNCTION drop_ccnew_indexes; + diff --git a/migrations/2022-09-07-113813_drop_ccnew_indexes_function/up.sql b/migrations/2022-09-07-113813_drop_ccnew_indexes_function/up.sql index 2a861aaf..0314b1dd 100644 --- a/migrations/2022-09-07-113813_drop_ccnew_indexes_function/up.sql +++ b/migrations/2022-09-07-113813_drop_ccnew_indexes_function/up.sql @@ -1,13 +1,21 @@ -CREATE OR REPLACE FUNCTION drop_ccnew_indexes() RETURNS INTEGER AS $$ +CREATE OR REPLACE FUNCTION drop_ccnew_indexes () + RETURNS integer + AS $$ DECLARE -i RECORD; + i RECORD; BEGIN - FOR i IN - (SELECT relname FROM pg_class WHERE relname like '%ccnew%') - LOOP - EXECUTE 'DROP INDEX ' || i.relname; - END LOOP; + FOR i IN ( + SELECT + relname + FROM + pg_class + WHERE + relname LIKE '%ccnew%') + LOOP + EXECUTE 'DROP INDEX ' || i.relname; + END LOOP; RETURN 1; - END; -$$ LANGUAGE plpgsql; +END; +$$ +LANGUAGE plpgsql; diff --git a/migrations/2022-09-07-114618_pm-reports/down.sql b/migrations/2022-09-07-114618_pm-reports/down.sql index 1db179af..46466d5e 100644 --- a/migrations/2022-09-07-114618_pm-reports/down.sql +++ b/migrations/2022-09-07-114618_pm-reports/down.sql @@ -1 +1,2 @@ -drop table private_message_report; +DROP TABLE private_message_report; + diff --git a/migrations/2022-09-07-114618_pm-reports/up.sql b/migrations/2022-09-07-114618_pm-reports/up.sql index 7574f7cf..aa168c33 100644 --- a/migrations/2022-09-07-114618_pm-reports/up.sql +++ b/migrations/2022-09-07-114618_pm-reports/up.sql @@ -1,12 +1,13 @@ -create table private_message_report ( - id serial primary key, - creator_id int references person on update cascade on delete cascade not null, -- user reporting comment - private_message_id int references private_message on update cascade on delete cascade not null, -- comment being reported - original_pm_text text not null, - reason text not null, - resolved bool not null default false, - resolver_id int references person on update cascade on delete cascade, -- user resolving report - published timestamp not null default now(), - updated timestamp null, - unique(private_message_id, creator_id) -- users should only be able to report a pm once +CREATE TABLE private_message_report ( + id serial PRIMARY KEY, + creator_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- user reporting comment + private_message_id int REFERENCES private_message ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, -- comment being reported + original_pm_text text NOT NULL, + reason text NOT NULL, + resolved bool NOT NULL DEFAULT FALSE, + resolver_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE, -- user resolving report + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL, + UNIQUE (private_message_id, creator_id) -- users should only be able to report a pm once ); + diff --git a/migrations/2022-09-08-102358_site-and-community-languages/down.sql b/migrations/2022-09-08-102358_site-and-community-languages/down.sql index eeff85b2..4cebf533 100644 --- a/migrations/2022-09-08-102358_site-and-community-languages/down.sql +++ b/migrations/2022-09-08-102358_site-and-community-languages/down.sql @@ -1,3 +1,6 @@ -drop table site_language; -drop table community_language; -delete from local_user_language; +DROP TABLE site_language; + +DROP TABLE community_language; + +DELETE FROM local_user_language; + diff --git a/migrations/2022-09-08-102358_site-and-community-languages/up.sql b/migrations/2022-09-08-102358_site-and-community-languages/up.sql index 7687c1b3..0f56b478 100644 --- a/migrations/2022-09-08-102358_site-and-community-languages/up.sql +++ b/migrations/2022-09-08-102358_site-and-community-languages/up.sql @@ -1,38 +1,62 @@ -create table site_language ( - id serial primary key, - site_id int references site on update cascade on delete cascade not null, - language_id int references language on update cascade on delete cascade not null, - unique (site_id, language_id) +CREATE TABLE site_language ( + id serial PRIMARY KEY, + site_id int REFERENCES site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + language_id int REFERENCES + LANGUAGE ON + UPDATE CASCADE ON DELETE CASCADE NOT NULL, + UNIQUE (site_id, language_id) ); -create table community_language ( - id serial primary key, - community_id int references community on update cascade on delete cascade not null, - language_id int references language on update cascade on delete cascade not null, - unique (community_id, language_id) +CREATE TABLE community_language ( + id serial PRIMARY KEY, + community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + language_id int REFERENCES + LANGUAGE ON + UPDATE CASCADE ON DELETE CASCADE NOT NULL, + UNIQUE (community_id, language_id) ); -- update existing users, sites and communities to have all languages enabled -do $$ - declare - xid integer; -begin - for xid in select id from local_user - loop - insert into local_user_language (local_user_id, language_id) - (select xid, language.id as lid from language); - end loop; - - for xid in select id from site - loop - insert into site_language (site_id, language_id) - (select xid, language.id as lid from language); - end loop; - - for xid in select id from community - loop - insert into community_language (community_id, language_id) - (select xid, language.id as lid from language); - end loop; -end; +DO $$ +DECLARE + xid integer; +BEGIN + FOR xid IN + SELECT + id + FROM + local_user LOOP + INSERT INTO local_user_language (local_user_id, language_id) ( + SELECT + xid, + language.id AS lid + FROM + LANGUAGE); + END LOOP; + FOR xid IN + SELECT + id + FROM + site LOOP + INSERT INTO site_language (site_id, language_id) ( + SELECT + xid, + language.id AS lid + FROM + LANGUAGE); + END LOOP; + FOR xid IN + SELECT + id + FROM + community LOOP + INSERT INTO community_language (community_id, language_id) ( + SELECT + xid, + language.id AS lid + FROM + LANGUAGE); + END LOOP; +END; $$; + diff --git a/migrations/2022-09-24-161829_remove_table_aliases/down.sql b/migrations/2022-09-24-161829_remove_table_aliases/down.sql index 39b439a0..7aac082b 100644 --- a/migrations/2022-09-24-161829_remove_table_aliases/down.sql +++ b/migrations/2022-09-24-161829_remove_table_aliases/down.sql @@ -1,2 +1,12 @@ -create view person_alias_1 as select * from person; -create view person_alias_2 as select * from person; +CREATE VIEW person_alias_1 AS +SELECT + * +FROM + person; + +CREATE VIEW person_alias_2 AS +SELECT + * +FROM + person; + diff --git a/migrations/2022-09-24-161829_remove_table_aliases/up.sql b/migrations/2022-09-24-161829_remove_table_aliases/up.sql index 36eabeca..f4ac9c77 100644 --- a/migrations/2022-09-24-161829_remove_table_aliases/up.sql +++ b/migrations/2022-09-24-161829_remove_table_aliases/up.sql @@ -1,2 +1,3 @@ -- Drop the alias views -drop view person_alias_1, person_alias_2; +DROP VIEW person_alias_1, person_alias_2; + diff --git a/migrations/2022-10-06-183632_move_blocklist_to_db/down.sql b/migrations/2022-10-06-183632_move_blocklist_to_db/down.sql index 3ca49b54..af95b877 100644 --- a/migrations/2022-10-06-183632_move_blocklist_to_db/down.sql +++ b/migrations/2022-10-06-183632_move_blocklist_to_db/down.sql @@ -1,63 +1,78 @@ -- Add back site columns -alter table site - add column enable_downvotes boolean default true not null, - add column open_registration boolean default true not null, - add column enable_nsfw boolean default true not null, - add column community_creation_admin_only boolean default false not null, - add column require_email_verification boolean default false not null, - add column require_application boolean default true not null, - add column application_question text default 'to verify that you are human, please explain why you want to create an account on this site'::text, - add column private_instance boolean default false not null, - add column default_theme text default 'browser'::text not null, - add column default_post_listing_type text default 'Local'::text not null, - add column legal_information text, - add column hide_modlog_mod_names boolean default true not null, - add column application_email_admins boolean default false not null; +ALTER TABLE site + ADD COLUMN enable_downvotes boolean DEFAULT TRUE NOT NULL, + ADD COLUMN open_registration boolean DEFAULT TRUE NOT NULL, + ADD COLUMN enable_nsfw boolean DEFAULT TRUE NOT NULL, + ADD COLUMN community_creation_admin_only boolean DEFAULT FALSE NOT NULL, + ADD COLUMN require_email_verification boolean DEFAULT FALSE NOT NULL, + ADD COLUMN require_application boolean DEFAULT TRUE NOT NULL, + ADD COLUMN application_question text DEFAULT 'to verify that you are human, please explain why you want to create an account on this site'::text, + ADD COLUMN private_instance boolean DEFAULT FALSE NOT NULL, + ADD COLUMN default_theme text DEFAULT 'browser'::text NOT NULL, + ADD COLUMN default_post_listing_type text DEFAULT 'Local'::text NOT NULL, + ADD COLUMN legal_information text, + ADD COLUMN hide_modlog_mod_names boolean DEFAULT TRUE NOT NULL, + ADD COLUMN application_email_admins boolean DEFAULT FALSE NOT NULL; -- Insert the data back from local_site -update site set - enable_downvotes = ls.enable_downvotes, - open_registration = ls.open_registration, - enable_nsfw = ls.enable_nsfw, - community_creation_admin_only = ls.community_creation_admin_only, - require_email_verification = ls.require_email_verification, - require_application = ls.require_application, - application_question = ls.application_question, - private_instance = ls.private_instance, - default_theme = ls.default_theme, - default_post_listing_type = ls.default_post_listing_type, - legal_information = ls.legal_information, - hide_modlog_mod_names = ls.hide_modlog_mod_names, - application_email_admins = ls.application_email_admins, - published = ls.published, - updated = ls.updated -from (select - site_id, - enable_downvotes, - open_registration, - enable_nsfw, - community_creation_admin_only, - require_email_verification, - require_application, - application_question, - private_instance, - default_theme, - default_post_listing_type, - legal_information, - hide_modlog_mod_names, - application_email_admins, - published, - updated -from local_site) as ls -where site.id = ls.site_id; +UPDATE + site +SET + enable_downvotes = ls.enable_downvotes, + open_registration = ls.open_registration, + enable_nsfw = ls.enable_nsfw, + community_creation_admin_only = ls.community_creation_admin_only, + require_email_verification = ls.require_email_verification, + require_application = ls.require_application, + application_question = ls.application_question, + private_instance = ls.private_instance, + default_theme = ls.default_theme, + default_post_listing_type = ls.default_post_listing_type, + legal_information = ls.legal_information, + hide_modlog_mod_names = ls.hide_modlog_mod_names, + application_email_admins = ls.application_email_admins, + published = ls.published, + updated = ls.updated +FROM ( + SELECT + site_id, + enable_downvotes, + open_registration, + enable_nsfw, + community_creation_admin_only, + require_email_verification, + require_application, + application_question, + private_instance, + default_theme, + default_post_listing_type, + legal_information, + hide_modlog_mod_names, + application_email_admins, + published, + updated + FROM + local_site) AS ls +WHERE + site.id = ls.site_id; -- drop instance columns -alter table site drop column instance_id; -alter table person drop column instance_id; -alter table community drop column instance_id; - -drop table local_site_rate_limit; -drop table local_site; -drop table federation_allowlist; -drop table federation_blocklist; -drop table instance; +ALTER TABLE site + DROP COLUMN instance_id; + +ALTER TABLE person + DROP COLUMN instance_id; + +ALTER TABLE community + DROP COLUMN instance_id; + +DROP TABLE local_site_rate_limit; + +DROP TABLE local_site; + +DROP TABLE federation_allowlist; + +DROP TABLE federation_blocklist; + +DROP TABLE instance; + diff --git a/migrations/2022-10-06-183632_move_blocklist_to_db/up.sql b/migrations/2022-10-06-183632_move_blocklist_to_db/up.sql index e814ce27..3b97dacc 100644 --- a/migrations/2022-10-06-183632_move_blocklist_to_db/up.sql +++ b/migrations/2022-10-06-183632_move_blocklist_to_db/up.sql @@ -1,186 +1,202 @@ -- Create an instance table -- Holds any connected or unconnected domain -create table instance ( - id serial primary key, - domain varchar(255) not null unique, - published timestamp not null default now(), - updated timestamp null +CREATE TABLE instance ( + id serial PRIMARY KEY, + domain varchar(255) NOT NULL UNIQUE, + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL ); -- Insert all the domains to the instance table -insert into instance (domain) -select distinct substring(p.actor_id from '(?:.*://)?(?:www\.)?([^/?]*)') from ( - select actor_id from site - union - select actor_id from person - union - select actor_id from community -) as p; +INSERT INTO instance (DOMAIN) +SELECT DISTINCT + substring(p.actor_id FROM '(?:.*://)?(?:www\.)?([^/?]*)') +FROM ( + SELECT + actor_id + FROM + site + UNION + SELECT + actor_id + FROM + person + UNION + SELECT + actor_id + FROM + community) AS p; -- Alter site, person, and community tables to reference the instance table. -alter table site add column -instance_id int references instance on update cascade on delete cascade; +ALTER TABLE site + ADD COLUMN instance_id int REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE; -alter table person add column -instance_id int references instance on update cascade on delete cascade; +ALTER TABLE person + ADD COLUMN instance_id int REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE; -alter table community add column -instance_id int references instance on update cascade on delete cascade; +ALTER TABLE community + ADD COLUMN instance_id int REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE; -- Add those columns -update site set instance_id = i.id -from instance i -where substring(actor_id from '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; +UPDATE + site +SET + instance_id = i.id +FROM + instance i +WHERE + substring(actor_id FROM '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; + +UPDATE + person +SET + instance_id = i.id +FROM + instance i +WHERE + substring(actor_id FROM '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; + +UPDATE + community +SET + instance_id = i.id +FROM + instance i +WHERE + substring(actor_id FROM '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; -update person set instance_id = i.id -from instance i -where substring(actor_id from '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; +-- Make those columns unique not null now +ALTER TABLE site + ALTER COLUMN instance_id SET NOT NULL; -update community set instance_id = i.id -from instance i -where substring(actor_id from '(?:.*://)?(?:www\.)?([^/?]*)') = i.domain; +ALTER TABLE site + ADD CONSTRAINT idx_site_instance_unique UNIQUE (instance_id); --- Make those columns unique not null now -alter table site alter column instance_id set not null; -alter table site add constraint idx_site_instance_unique unique (instance_id); +ALTER TABLE person + ALTER COLUMN instance_id SET NOT NULL; -alter table person alter column instance_id set not null; -alter table community alter column instance_id set not null; +ALTER TABLE community + ALTER COLUMN instance_id SET NOT NULL; -- Create allowlist and blocklist tables -create table federation_allowlist ( - id serial primary key, - instance_id int references instance on update cascade on delete cascade not null unique, - published timestamp not null default now(), - updated timestamp null +CREATE TABLE federation_allowlist ( + id serial PRIMARY KEY, + instance_id int REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE NOT NULL UNIQUE, + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL ); -create table federation_blocklist ( - id serial primary key, - instance_id int references instance on update cascade on delete cascade not null unique, - published timestamp not null default now(), - updated timestamp null +CREATE TABLE federation_blocklist ( + id serial PRIMARY KEY, + instance_id int REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE NOT NULL UNIQUE, + published timestamp NOT NULL DEFAULT now(), + updated timestamp NULL ); -- Move all the extra site settings-type columns to a local_site table -- Add a lot of other fields currently in the lemmy.hjson -create table local_site ( - id serial primary key, - site_id int references site on update cascade on delete cascade not null unique, - - -- Site table fields - site_setup boolean default false not null, - enable_downvotes boolean default true not null, - open_registration boolean default true not null, - enable_nsfw boolean default true not null, - community_creation_admin_only boolean default false not null, - require_email_verification boolean default false not null, - require_application boolean default true not null, - application_question text default 'to verify that you are human, please explain why you want to create an account on this site'::text, - private_instance boolean default false not null, - default_theme text default 'browser'::text not null, - default_post_listing_type text default 'Local'::text not null, - legal_information text, - hide_modlog_mod_names boolean default true not null, - application_email_admins boolean default false not null, - - -- Fields from lemmy.hjson - slur_filter_regex text, - actor_name_max_length int default 20 not null, - federation_enabled boolean default true not null, - federation_debug boolean default false not null, - federation_strict_allowlist boolean default true not null, - federation_http_fetch_retry_limit int default 25 not null, - federation_worker_count int default 64 not null, - captcha_enabled boolean default false not null, - captcha_difficulty varchar(255) default 'medium' not null, - - -- Time fields - published timestamp without time zone default now() not null, - updated timestamp without time zone +CREATE TABLE local_site ( + id serial PRIMARY KEY, + site_id int REFERENCES site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL UNIQUE, + -- Site table fields + site_setup boolean DEFAULT FALSE NOT NULL, + enable_downvotes boolean DEFAULT TRUE NOT NULL, + open_registration boolean DEFAULT TRUE NOT NULL, + enable_nsfw boolean DEFAULT TRUE NOT NULL, + community_creation_admin_only boolean DEFAULT FALSE NOT NULL, + require_email_verification boolean DEFAULT FALSE NOT NULL, + require_application boolean DEFAULT TRUE NOT NULL, + application_question text DEFAULT 'to verify that you are human, please explain why you want to create an account on this site' ::text, + private_instance boolean DEFAULT FALSE NOT NULL, + default_theme text DEFAULT 'browser' ::text NOT NULL, + default_post_listing_type text DEFAULT 'Local' ::text NOT NULL, + legal_information text, + hide_modlog_mod_names boolean DEFAULT TRUE NOT NULL, + application_email_admins boolean DEFAULT FALSE NOT NULL, + -- Fields from lemmy.hjson + slur_filter_regex text, + actor_name_max_length int DEFAULT 20 NOT NULL, + federation_enabled boolean DEFAULT TRUE NOT NULL, + federation_debug boolean DEFAULT FALSE NOT NULL, + federation_strict_allowlist boolean DEFAULT TRUE NOT NULL, + federation_http_fetch_retry_limit int DEFAULT 25 NOT NULL, + federation_worker_count int DEFAULT 64 NOT NULL, + captcha_enabled boolean DEFAULT FALSE NOT NULL, + captcha_difficulty varchar(255) DEFAULT 'medium' NOT NULL, + -- Time fields + published timestamp without time zone DEFAULT now() NOT NULL, + updated timestamp without time zone ); -- local_site_rate_limit is its own table, so as to not go over 32 columns, and force diesel to use the 64-column-tables feature -create table local_site_rate_limit ( - id serial primary key, - local_site_id int references local_site on update cascade on delete cascade not null unique, - message int default 180 not null, - message_per_second int default 60 not null, - post int default 6 not null, - post_per_second int default 600 not null, - register int default 3 not null, - register_per_second int default 3600 not null, - image int default 6 not null, - image_per_second int default 3600 not null, - comment int default 6 not null, - comment_per_second int default 600 not null, - search int default 60 not null, - search_per_second int default 600 not null, - published timestamp without time zone default now() not null, - updated timestamp without time zone +CREATE TABLE local_site_rate_limit ( + id serial PRIMARY KEY, + local_site_id int REFERENCES local_site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL UNIQUE, + message int DEFAULT 180 NOT NULL, + message_per_second int DEFAULT 60 NOT NULL, + post int DEFAULT 6 NOT NULL, + post_per_second int DEFAULT 600 NOT NULL, + register int DEFAULT 3 NOT NULL, + register_per_second int DEFAULT 3600 NOT NULL, + image int DEFAULT 6 NOT NULL, + image_per_second int DEFAULT 3600 NOT NULL, + comment int DEFAULT 6 NOT NULL, + comment_per_second int DEFAULT 600 NOT NULL, + search int DEFAULT 60 NOT NULL, + search_per_second int DEFAULT 600 NOT NULL, + published timestamp without time zone DEFAULT now() NOT NULL, + updated timestamp without time zone ); -- Insert the data into local_site -insert into local_site ( - site_id, - site_setup, - enable_downvotes, - open_registration, - enable_nsfw, - community_creation_admin_only, - require_email_verification, - require_application, - application_question, - private_instance, - default_theme, - default_post_listing_type, - legal_information, - hide_modlog_mod_names, - application_email_admins, - published, - updated -) -select - id, - true, -- Assume site if setup if there's already a site row - enable_downvotes, - open_registration, - enable_nsfw, - community_creation_admin_only, - require_email_verification, - require_application, - application_question, - private_instance, - default_theme, - default_post_listing_type, - legal_information, - hide_modlog_mod_names, - application_email_admins, - published, - updated -from site -order by id limit 1; +INSERT INTO local_site (site_id, site_setup, enable_downvotes, open_registration, enable_nsfw, community_creation_admin_only, require_email_verification, require_application, application_question, private_instance, default_theme, default_post_listing_type, legal_information, hide_modlog_mod_names, application_email_admins, published, updated) +SELECT + id, + TRUE, -- Assume site if setup if there's already a site row + enable_downvotes, + open_registration, + enable_nsfw, + community_creation_admin_only, + require_email_verification, + require_application, + application_question, + private_instance, + default_theme, + default_post_listing_type, + legal_information, + hide_modlog_mod_names, + application_email_admins, + published, + updated +FROM + site +ORDER BY + id +LIMIT 1; -- Default here -insert into local_site_rate_limit ( - local_site_id -) -select id from local_site -order by id limit 1; +INSERT INTO local_site_rate_limit (local_site_id) +SELECT + id +FROM + local_site +ORDER BY + id +LIMIT 1; -- Drop all those columns from site -alter table site - drop column enable_downvotes, - drop column open_registration, - drop column enable_nsfw, - drop column community_creation_admin_only, - drop column require_email_verification, - drop column require_application, - drop column application_question, - drop column private_instance, - drop column default_theme, - drop column default_post_listing_type, - drop column legal_information, - drop column hide_modlog_mod_names, - drop column application_email_admins; +ALTER TABLE site + DROP COLUMN enable_downvotes, + DROP COLUMN open_registration, + DROP COLUMN enable_nsfw, + DROP COLUMN community_creation_admin_only, + DROP COLUMN require_email_verification, + DROP COLUMN require_application, + DROP COLUMN application_question, + DROP COLUMN private_instance, + DROP COLUMN default_theme, + DROP COLUMN default_post_listing_type, + DROP COLUMN legal_information, + DROP COLUMN hide_modlog_mod_names, + DROP COLUMN application_email_admins; diff --git a/migrations/2022-11-13-181529_create_taglines/down.sql b/migrations/2022-11-13-181529_create_taglines/down.sql index 4867e5f1..5471b4b7 100644 --- a/migrations/2022-11-13-181529_create_taglines/down.sql +++ b/migrations/2022-11-13-181529_create_taglines/down.sql @@ -1 +1,2 @@ -drop table tagline; \ No newline at end of file +DROP TABLE tagline; + diff --git a/migrations/2022-11-13-181529_create_taglines/up.sql b/migrations/2022-11-13-181529_create_taglines/up.sql index ff88cf4c..ed4daa63 100644 --- a/migrations/2022-11-13-181529_create_taglines/up.sql +++ b/migrations/2022-11-13-181529_create_taglines/up.sql @@ -1,7 +1,8 @@ -create table tagline ( - id serial primary key, - local_site_id int references local_site on update cascade on delete cascade not null, - content text not null, - published timestamp without time zone default now() not null, - updated timestamp without time zone -); \ No newline at end of file +CREATE TABLE tagline ( + id serial PRIMARY KEY, + local_site_id int REFERENCES local_site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + content text NOT NULL, + published timestamp without time zone DEFAULT now() NOT NULL, + updated timestamp without time zone +); + diff --git a/migrations/2022-11-20-032430_sticky_local/down.sql b/migrations/2022-11-20-032430_sticky_local/down.sql index 46a2b6a9..767c9aa7 100644 --- a/migrations/2022-11-20-032430_sticky_local/down.sql +++ b/migrations/2022-11-20-032430_sticky_local/down.sql @@ -1,47 +1,67 @@ - DROP TRIGGER IF EXISTS post_aggregates_featured_local ON post; + DROP TRIGGER IF EXISTS post_aggregates_featured_community ON post; -drop function post_aggregates_featured_community; -drop function post_aggregates_featured_local; - - -alter table post ADD stickied boolean NOT NULL DEFAULT false; -Update post -set stickied = featured_community; -alter table post DROP COLUMN featured_community; -alter table post DROP COLUMN featured_local; - -alter table post_aggregates ADD stickied boolean NOT NULL DEFAULT false; -Update post_aggregates -set stickied = featured_community; -alter table post_aggregates DROP COLUMN featured_community; -alter table post_aggregates DROP COLUMN featured_local; - -alter table mod_feature_post -rename column featured TO stickied; - -alter table mod_feature_post -DROP COLUMN is_featured_community; - -alter table mod_feature_post -alter column stickied DROP NOT NULL; - -alter table mod_feature_post -Rename To mod_sticky_post; - -create function post_aggregates_stickied() -returns trigger language plpgsql -as $$ -begin - update post_aggregates pa - set stickied = NEW.stickied - where pa.post_id = NEW.id; - - return null; -end $$; - -create trigger post_aggregates_stickied -after update on post -for each row -when (OLD.stickied is distinct from NEW.stickied) -execute procedure post_aggregates_stickied(); \ No newline at end of file + +DROP FUNCTION post_aggregates_featured_community; + +DROP FUNCTION post_aggregates_featured_local; + +ALTER TABLE post + ADD stickied boolean NOT NULL DEFAULT FALSE; + +UPDATE + post +SET + stickied = featured_community; + +ALTER TABLE post + DROP COLUMN featured_community; + +ALTER TABLE post + DROP COLUMN featured_local; + +ALTER TABLE post_aggregates + ADD stickied boolean NOT NULL DEFAULT FALSE; + +UPDATE + post_aggregates +SET + stickied = featured_community; + +ALTER TABLE post_aggregates + DROP COLUMN featured_community; + +ALTER TABLE post_aggregates + DROP COLUMN featured_local; + +ALTER TABLE mod_feature_post RENAME COLUMN featured TO stickied; + +ALTER TABLE mod_feature_post + DROP COLUMN is_featured_community; + +ALTER TABLE mod_feature_post + ALTER COLUMN stickied DROP NOT NULL; + +ALTER TABLE mod_feature_post RENAME TO mod_sticky_post; + +CREATE FUNCTION post_aggregates_stickied () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + post_aggregates pa + SET + stickied = NEW.stickied + WHERE + pa.post_id = NEW.id; + RETURN NULL; +END +$$; + +CREATE TRIGGER post_aggregates_stickied + AFTER UPDATE ON post + FOR EACH ROW + WHEN (OLD.stickied IS DISTINCT FROM NEW.stickied) + EXECUTE PROCEDURE post_aggregates_stickied (); + diff --git a/migrations/2022-11-20-032430_sticky_local/up.sql b/migrations/2022-11-20-032430_sticky_local/up.sql index 202c4c4b..0411256d 100644 --- a/migrations/2022-11-20-032430_sticky_local/up.sql +++ b/migrations/2022-11-20-032430_sticky_local/up.sql @@ -1,63 +1,84 @@ - DROP TRIGGER IF EXISTS post_aggregates_stickied ON post; -drop function - post_aggregates_stickied; - - -alter table post ADD featured_community boolean NOT NULL DEFAULT false; -alter table post ADD featured_local boolean NOT NULL DEFAULT false; -update post -set featured_community = stickied; -alter table post DROP COLUMN stickied; - -alter table post_aggregates ADD featured_community boolean NOT NULL DEFAULT false; -alter table post_aggregates ADD featured_local boolean NOT NULL DEFAULT false; -update post_aggregates -set featured_community = stickied; -alter table post_aggregates DROP COLUMN stickied; - -alter table mod_sticky_post -rename column stickied TO featured; - -alter table mod_sticky_post -alter column featured SET NOT NULL; - -alter table mod_sticky_post -ADD is_featured_community boolean NOT NULL DEFAULT true; - -alter table mod_sticky_post -Rename To mod_feature_post; - -create function post_aggregates_featured_community() -returns trigger language plpgsql -as $$ -begin - update post_aggregates pa - set featured_community = NEW.featured_community - where pa.post_id = NEW.id; - return null; -end $$; - -create function post_aggregates_featured_local() -returns trigger language plpgsql -as $$ -begin - update post_aggregates pa - set featured_local = NEW.featured_local - where pa.post_id = NEW.id; - return null; -end $$; + +DROP FUNCTION post_aggregates_stickied; + +ALTER TABLE post + ADD featured_community boolean NOT NULL DEFAULT FALSE; + +ALTER TABLE post + ADD featured_local boolean NOT NULL DEFAULT FALSE; + +UPDATE + post +SET + featured_community = stickied; + +ALTER TABLE post + DROP COLUMN stickied; + +ALTER TABLE post_aggregates + ADD featured_community boolean NOT NULL DEFAULT FALSE; + +ALTER TABLE post_aggregates + ADD featured_local boolean NOT NULL DEFAULT FALSE; + +UPDATE + post_aggregates +SET + featured_community = stickied; + +ALTER TABLE post_aggregates + DROP COLUMN stickied; + +ALTER TABLE mod_sticky_post RENAME COLUMN stickied TO featured; + +ALTER TABLE mod_sticky_post + ALTER COLUMN featured SET NOT NULL; + +ALTER TABLE mod_sticky_post + ADD is_featured_community boolean NOT NULL DEFAULT TRUE; + +ALTER TABLE mod_sticky_post RENAME TO mod_feature_post; + +CREATE FUNCTION post_aggregates_featured_community () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + post_aggregates pa + SET + featured_community = NEW.featured_community + WHERE + pa.post_id = NEW.id; + RETURN NULL; +END +$$; + +CREATE FUNCTION post_aggregates_featured_local () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + UPDATE + post_aggregates pa + SET + featured_local = NEW.featured_local + WHERE + pa.post_id = NEW.id; + RETURN NULL; +END +$$; CREATE TRIGGER post_aggregates_featured_community - AFTER UPDATE - ON public.post + AFTER UPDATE ON public.post FOR EACH ROW WHEN (old.featured_community IS DISTINCT FROM new.featured_community) - EXECUTE FUNCTION public.post_aggregates_featured_community(); + EXECUTE FUNCTION public.post_aggregates_featured_community (); CREATE TRIGGER post_aggregates_featured_local - AFTER UPDATE - ON public.post + AFTER UPDATE ON public.post FOR EACH ROW WHEN (old.featured_local IS DISTINCT FROM new.featured_local) - EXECUTE FUNCTION public.post_aggregates_featured_local(); \ No newline at end of file + EXECUTE FUNCTION public.post_aggregates_featured_local (); + diff --git a/migrations/2022-11-21-143249_remove-federation-settings/down.sql b/migrations/2022-11-21-143249_remove-federation-settings/down.sql index 51452e19..066775ea 100644 --- a/migrations/2022-11-21-143249_remove-federation-settings/down.sql +++ b/migrations/2022-11-21-143249_remove-federation-settings/down.sql @@ -1,2 +1,6 @@ -alter table local_site add column federation_strict_allowlist bool default true not null; -alter table local_site add column federation_http_fetch_retry_limit int not null default 25; +ALTER TABLE local_site + ADD COLUMN federation_strict_allowlist bool DEFAULT TRUE NOT NULL; + +ALTER TABLE local_site + ADD COLUMN federation_http_fetch_retry_limit int NOT NULL DEFAULT 25; + diff --git a/migrations/2022-11-21-143249_remove-federation-settings/up.sql b/migrations/2022-11-21-143249_remove-federation-settings/up.sql index e1756304..6b2b3593 100644 --- a/migrations/2022-11-21-143249_remove-federation-settings/up.sql +++ b/migrations/2022-11-21-143249_remove-federation-settings/up.sql @@ -1,2 +1,6 @@ -alter table local_site drop column federation_strict_allowlist; -alter table local_site drop column federation_http_fetch_retry_limit; +ALTER TABLE local_site + DROP COLUMN federation_strict_allowlist; + +ALTER TABLE local_site + DROP COLUMN federation_http_fetch_retry_limit; + diff --git a/migrations/2022-11-21-204256_user-following/down.sql b/migrations/2022-11-21-204256_user-following/down.sql index 10118ba9..1803d4d6 100644 --- a/migrations/2022-11-21-204256_user-following/down.sql +++ b/migrations/2022-11-21-204256_user-following/down.sql @@ -1,3 +1,5 @@ -drop table person_follower; +DROP TABLE person_follower; + +ALTER TABLE community_follower + ALTER COLUMN pending DROP NOT NULL; -alter table community_follower alter column pending drop not null; diff --git a/migrations/2022-11-21-204256_user-following/up.sql b/migrations/2022-11-21-204256_user-following/up.sql index 0ef6e8be..26456b84 100644 --- a/migrations/2022-11-21-204256_user-following/up.sql +++ b/migrations/2022-11-21-204256_user-following/up.sql @@ -1,12 +1,20 @@ -- create user follower table with two references to persons -create table person_follower ( - id serial primary key, - person_id int references person on update cascade on delete cascade not null, - follower_id int references person on update cascade on delete cascade not null, - published timestamp not null default now(), - pending boolean not null, - unique (follower_id, person_id) +CREATE TABLE person_follower ( + id serial PRIMARY KEY, + person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + follower_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + published timestamp NOT NULL DEFAULT now(), + pending boolean NOT NULL, + UNIQUE (follower_id, person_id) ); -update community_follower set pending = false where pending is null; -alter table community_follower alter column pending set not null; +UPDATE + community_follower +SET + pending = FALSE +WHERE + pending IS NULL; + +ALTER TABLE community_follower + ALTER COLUMN pending SET NOT NULL; + diff --git a/migrations/2022-12-05-110642_registration_mode/down.sql b/migrations/2022-12-05-110642_registration_mode/down.sql index 25bb36c0..9b118ecd 100644 --- a/migrations/2022-12-05-110642_registration_mode/down.sql +++ b/migrations/2022-12-05-110642_registration_mode/down.sql @@ -1,31 +1,48 @@ -- add back old registration columns -alter table local_site add column open_registration boolean not null default true; -alter table local_site add column require_application boolean not null default true; +ALTER TABLE local_site + ADD COLUMN open_registration boolean NOT NULL DEFAULT TRUE; + +ALTER TABLE local_site + ADD COLUMN require_application boolean NOT NULL DEFAULT TRUE; -- regenerate their values -with subquery as ( - select registration_mode, - case - when registration_mode='closed' then false - else true - end - from local_site -) -update local_site -set open_registration = subquery.case -from subquery; -with subquery as ( - select registration_mode, - case - when registration_mode='open' then false - else true - end - from local_site -) -update local_site -set require_application = subquery.case -from subquery; +WITH subquery AS ( + SELECT + registration_mode, + CASE WHEN registration_mode = 'closed' THEN + FALSE + ELSE + TRUE + END + FROM + local_site) +UPDATE + local_site +SET + open_registration = subquery.case +FROM + subquery; + +WITH subquery AS ( + SELECT + registration_mode, + CASE WHEN registration_mode = 'open' THEN + FALSE + ELSE + TRUE + END + FROM + local_site) +UPDATE + local_site +SET + require_application = subquery.case +FROM + subquery; -- drop new column and type -alter table local_site drop column registration_mode; -drop type registration_mode_enum; \ No newline at end of file +ALTER TABLE local_site + DROP COLUMN registration_mode; + +DROP TYPE registration_mode_enum; + diff --git a/migrations/2022-12-05-110642_registration_mode/up.sql b/migrations/2022-12-05-110642_registration_mode/up.sql index 34515e2c..7f4d45ff 100644 --- a/migrations/2022-12-05-110642_registration_mode/up.sql +++ b/migrations/2022-12-05-110642_registration_mode/up.sql @@ -1,25 +1,40 @@ -- create enum for registration modes -create type registration_mode_enum as enum - ('closed', 'require_application', 'open'); +CREATE TYPE registration_mode_enum AS enum ( + 'closed', + 'require_application', + 'open' +); -- use this enum for registration mode setting -alter table local_site add column - registration_mode registration_mode_enum not null default 'require_application'; +ALTER TABLE local_site + ADD COLUMN registration_mode registration_mode_enum NOT NULL DEFAULT 'require_application'; -- generate registration mode value from previous settings -with subquery as ( - select open_registration, require_application, - case - when open_registration=false then 'closed'::registration_mode_enum - when open_registration=true and require_application=true then 'require_application' - else 'open' - end - from local_site -) -update local_site -set registration_mode = subquery.case -from subquery; +WITH subquery AS ( + SELECT + open_registration, + require_application, + CASE WHEN open_registration = FALSE THEN + 'closed'::registration_mode_enum + WHEN open_registration = TRUE + AND require_application = TRUE THEN + 'require_application' + ELSE + 'open' + END + FROM + local_site) +UPDATE + local_site +SET + registration_mode = subquery.case +FROM + subquery; -- drop old registration settings -alter table local_site drop column open_registration; -alter table local_site drop column require_application; +ALTER TABLE local_site + DROP COLUMN open_registration; + +ALTER TABLE local_site + DROP COLUMN require_application; + diff --git a/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/down.sql b/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/down.sql index d91843e1..9064ea76 100644 --- a/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/down.sql +++ b/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/down.sql @@ -1,22 +1,16 @@ -- Drop the new indexes -drop index idx_post_aggregates_featured_local_newest_comment_time, - idx_post_aggregates_featured_community_newest_comment_time, - idx_post_aggregates_featured_local_comments, - idx_post_aggregates_featured_community_comments, - idx_post_aggregates_featured_local_hot, - idx_post_aggregates_featured_community_hot, - idx_post_aggregates_featured_local_active, - idx_post_aggregates_featured_community_active, - idx_post_aggregates_featured_local_score, - idx_post_aggregates_featured_community_score, - idx_post_aggregates_featured_local_published, - idx_post_aggregates_featured_community_published; +DROP INDEX idx_post_aggregates_featured_local_newest_comment_time, idx_post_aggregates_featured_community_newest_comment_time, idx_post_aggregates_featured_local_comments, idx_post_aggregates_featured_community_comments, idx_post_aggregates_featured_local_hot, idx_post_aggregates_featured_community_hot, idx_post_aggregates_featured_local_active, idx_post_aggregates_featured_community_active, idx_post_aggregates_featured_local_score, idx_post_aggregates_featured_community_score, idx_post_aggregates_featured_local_published, idx_post_aggregates_featured_community_published; -- Create the old indexes -create index idx_post_aggregates_newest_comment_time on post_aggregates (newest_comment_time desc); -create index idx_post_aggregates_comments on post_aggregates (comments desc); -create index idx_post_aggregates_hot on post_aggregates (hot_rank(score, published) desc, published desc); -create index idx_post_aggregates_active on post_aggregates (hot_rank(score, newest_comment_time) desc, newest_comment_time desc); -create index idx_post_aggregates_score on post_aggregates (score desc); -create index idx_post_aggregates_published on post_aggregates (published desc); +CREATE INDEX idx_post_aggregates_newest_comment_time ON post_aggregates (newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_comments ON post_aggregates (comments DESC); + +CREATE INDEX idx_post_aggregates_hot ON post_aggregates (hot_rank (score, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_active ON post_aggregates (hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_score ON post_aggregates (score DESC); + +CREATE INDEX idx_post_aggregates_published ON post_aggregates (published DESC); diff --git a/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/up.sql b/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/up.sql index 88108929..29f571cc 100644 --- a/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/up.sql +++ b/migrations/2023-01-17-165819_cleanup_post_aggregates_indexes/up.sql @@ -1,30 +1,30 @@ -- Drop the old indexes -drop index idx_post_aggregates_newest_comment_time, - idx_post_aggregates_comments, - idx_post_aggregates_hot, - idx_post_aggregates_active, - idx_post_aggregates_score, - idx_post_aggregates_published; - --- All of the post fetching queries now start with either +DROP INDEX idx_post_aggregates_newest_comment_time, idx_post_aggregates_comments, idx_post_aggregates_hot, idx_post_aggregates_active, idx_post_aggregates_score, idx_post_aggregates_published; + +-- All of the post fetching queries now start with either -- featured_local desc, or featured_community desc, then the other sorts. -- So you now need to double these indexes +CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time ON post_aggregates (featured_local DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time ON post_aggregates (featured_community DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_featured_local_comments ON post_aggregates (featured_local DESC, comments DESC); + +CREATE INDEX idx_post_aggregates_featured_community_comments ON post_aggregates (featured_community DESC, comments DESC); + +CREATE INDEX idx_post_aggregates_featured_local_hot ON post_aggregates (featured_local DESC, hot_rank (score, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_community_hot ON post_aggregates (featured_community DESC, hot_rank (score, published) DESC, published DESC); -create index idx_post_aggregates_featured_local_newest_comment_time on post_aggregates (featured_local desc, newest_comment_time desc); -create index idx_post_aggregates_featured_community_newest_comment_time on post_aggregates (featured_community desc, newest_comment_time desc); +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); -create index idx_post_aggregates_featured_local_comments on post_aggregates (featured_local desc, comments desc); -create index idx_post_aggregates_featured_community_comments on post_aggregates (featured_community desc, comments desc); +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); -create index idx_post_aggregates_featured_local_hot on post_aggregates (featured_local desc, hot_rank(score, published) desc, published desc); -create index idx_post_aggregates_featured_community_hot on post_aggregates (featured_community desc, hot_rank(score, published) desc, published desc); +CREATE INDEX idx_post_aggregates_featured_local_score ON post_aggregates (featured_local DESC, score DESC); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank(score, newest_comment_time) desc, newest_comment_time desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank(score, newest_comment_time) desc, newest_comment_time desc); +CREATE INDEX idx_post_aggregates_featured_community_score ON post_aggregates (featured_community DESC, score DESC); -create index idx_post_aggregates_featured_local_score on post_aggregates (featured_local desc, score desc); -create index idx_post_aggregates_featured_community_score on post_aggregates (featured_community desc, score desc); +CREATE INDEX idx_post_aggregates_featured_local_published ON post_aggregates (featured_local DESC, published DESC); -create index idx_post_aggregates_featured_local_published on post_aggregates (featured_local desc, published desc); -create index idx_post_aggregates_featured_community_published on post_aggregates (featured_community desc, published desc); +CREATE INDEX idx_post_aggregates_featured_community_published ON post_aggregates (featured_community DESC, published DESC); diff --git a/migrations/2023-02-01-012747_fix_active_index/down.sql b/migrations/2023-02-01-012747_fix_active_index/down.sql index 356e3b8c..20be3105 100644 --- a/migrations/2023-02-01-012747_fix_active_index/down.sql +++ b/migrations/2023-02-01-012747_fix_active_index/down.sql @@ -1,6 +1,6 @@ -drop index - idx_post_aggregates_featured_local_active, - idx_post_aggregates_featured_community_active; +DROP INDEX idx_post_aggregates_featured_local_active, idx_post_aggregates_featured_community_active; + +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank (score, newest_comment_time) DESC, newest_comment_time DESC); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank(score, newest_comment_time) desc, newest_comment_time desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank(score, newest_comment_time) desc, newest_comment_time desc); diff --git a/migrations/2023-02-01-012747_fix_active_index/up.sql b/migrations/2023-02-01-012747_fix_active_index/up.sql index 5673cf45..2219ebc7 100644 --- a/migrations/2023-02-01-012747_fix_active_index/up.sql +++ b/migrations/2023-02-01-012747_fix_active_index/up.sql @@ -1,7 +1,7 @@ -- This should use the newest_comment_time_necro, not the newest_comment_time for the hot_rank -drop index - idx_post_aggregates_featured_local_active, - idx_post_aggregates_featured_community_active; +DROP INDEX idx_post_aggregates_featured_local_active, idx_post_aggregates_featured_community_active; + +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank (score, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank (score, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank(score, newest_comment_time_necro) desc, newest_comment_time_necro desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank(score, newest_comment_time_necro) desc, newest_comment_time_necro desc); diff --git a/migrations/2023-02-05-102549_drop-site-federation-debug/down.sql b/migrations/2023-02-05-102549_drop-site-federation-debug/down.sql index 1ac320f2..4e141e42 100644 --- a/migrations/2023-02-05-102549_drop-site-federation-debug/down.sql +++ b/migrations/2023-02-05-102549_drop-site-federation-debug/down.sql @@ -1 +1,3 @@ -alter table local_site add column federation_debug int default 0; \ No newline at end of file +ALTER TABLE local_site + ADD COLUMN federation_debug int DEFAULT 0; + diff --git a/migrations/2023-02-05-102549_drop-site-federation-debug/up.sql b/migrations/2023-02-05-102549_drop-site-federation-debug/up.sql index c7286d09..cad1c897 100644 --- a/migrations/2023-02-05-102549_drop-site-federation-debug/up.sql +++ b/migrations/2023-02-05-102549_drop-site-federation-debug/up.sql @@ -1 +1,3 @@ -alter table local_site drop column federation_debug; \ No newline at end of file +ALTER TABLE local_site + DROP COLUMN federation_debug; + diff --git a/migrations/2023-02-07-030958_community-collections/down.sql b/migrations/2023-02-07-030958_community-collections/down.sql index 8f7b531f..e3aa8bad 100644 --- a/migrations/2023-02-07-030958_community-collections/down.sql +++ b/migrations/2023-02-07-030958_community-collections/down.sql @@ -1,2 +1,6 @@ -alter table community drop column moderators_url; -alter table community drop column featured_url; \ No newline at end of file +ALTER TABLE community + DROP COLUMN moderators_url; + +ALTER TABLE community + DROP COLUMN featured_url; + diff --git a/migrations/2023-02-07-030958_community-collections/up.sql b/migrations/2023-02-07-030958_community-collections/up.sql index 78e7e52b..f8be41a9 100644 --- a/migrations/2023-02-07-030958_community-collections/up.sql +++ b/migrations/2023-02-07-030958_community-collections/up.sql @@ -1,2 +1,6 @@ -alter table community add column moderators_url varchar(255) unique; -alter table community add column featured_url varchar(255) unique; \ No newline at end of file +ALTER TABLE community + ADD COLUMN moderators_url varchar(255) UNIQUE; + +ALTER TABLE community + ADD COLUMN featured_url varchar(255) UNIQUE; + diff --git a/migrations/2023-02-11-173347_custom_emojis/down.sql b/migrations/2023-02-11-173347_custom_emojis/down.sql index 8994bb3b..01a68d2d 100644 --- a/migrations/2023-02-11-173347_custom_emojis/down.sql +++ b/migrations/2023-02-11-173347_custom_emojis/down.sql @@ -1,2 +1,4 @@ -drop table custom_emoji_keyword; -drop table custom_emoji; \ No newline at end of file +DROP TABLE custom_emoji_keyword; + +DROP TABLE custom_emoji; + diff --git a/migrations/2023-02-11-173347_custom_emojis/up.sql b/migrations/2023-02-11-173347_custom_emojis/up.sql index 79a21b20..98b6fa59 100644 --- a/migrations/2023-02-11-173347_custom_emojis/up.sql +++ b/migrations/2023-02-11-173347_custom_emojis/up.sql @@ -1,19 +1,20 @@ -create table custom_emoji ( - id serial primary key, - local_site_id int references local_site on update cascade on delete cascade not null, - shortcode varchar(128) not null UNIQUE, - image_url text not null UNIQUE, - alt_text text not null, - category text not null, - published timestamp without time zone default now() not null, - updated timestamp without time zone +CREATE TABLE custom_emoji ( + id serial PRIMARY KEY, + local_site_id int REFERENCES local_site ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + shortcode varchar(128) NOT NULL UNIQUE, + image_url text NOT NULL UNIQUE, + alt_text text NOT NULL, + category text NOT NULL, + published timestamp without time zone DEFAULT now() NOT NULL, + updated timestamp without time zone ); -create table custom_emoji_keyword ( - id serial primary key, - custom_emoji_id int references custom_emoji on update cascade on delete cascade not null, - keyword varchar(128) not null, - UNIQUE (custom_emoji_id, keyword) +CREATE TABLE custom_emoji_keyword ( + id serial PRIMARY KEY, + custom_emoji_id int REFERENCES custom_emoji ON UPDATE CASCADE ON DELETE CASCADE NOT NULL, + keyword varchar(128) NOT NULL, + UNIQUE (custom_emoji_id, keyword) ); -create index idx_custom_emoji_category on custom_emoji (id,category); +CREATE INDEX idx_custom_emoji_category ON custom_emoji (id, category); + diff --git a/migrations/2023-02-13-172528_add_report_email_admins/down.sql b/migrations/2023-02-13-172528_add_report_email_admins/down.sql index fa69bbaf..148f35d9 100644 --- a/migrations/2023-02-13-172528_add_report_email_admins/down.sql +++ b/migrations/2023-02-13-172528_add_report_email_admins/down.sql @@ -1 +1,3 @@ -alter table local_site drop column reports_email_admins; +ALTER TABLE local_site + DROP COLUMN reports_email_admins; + diff --git a/migrations/2023-02-13-172528_add_report_email_admins/up.sql b/migrations/2023-02-13-172528_add_report_email_admins/up.sql index 7de8a284..069df145 100644 --- a/migrations/2023-02-13-172528_add_report_email_admins/up.sql +++ b/migrations/2023-02-13-172528_add_report_email_admins/up.sql @@ -1,2 +1,4 @@ -- Adding a field to email admins for new reports -alter table local_site add column reports_email_admins boolean not null default false; +ALTER TABLE local_site + ADD COLUMN reports_email_admins boolean NOT NULL DEFAULT FALSE; + diff --git a/migrations/2023-02-13-221303_add_instance_software_and_version/down.sql b/migrations/2023-02-13-221303_add_instance_software_and_version/down.sql index 07179de1..fbac63e1 100644 --- a/migrations/2023-02-13-221303_add_instance_software_and_version/down.sql +++ b/migrations/2023-02-13-221303_add_instance_software_and_version/down.sql @@ -1,2 +1,6 @@ -alter table instance drop column software; -alter table instance drop column version; +ALTER TABLE instance + DROP COLUMN software; + +ALTER TABLE instance + DROP COLUMN version; + diff --git a/migrations/2023-02-13-221303_add_instance_software_and_version/up.sql b/migrations/2023-02-13-221303_add_instance_software_and_version/up.sql index abfeb850..a7f7233c 100644 --- a/migrations/2023-02-13-221303_add_instance_software_and_version/up.sql +++ b/migrations/2023-02-13-221303_add_instance_software_and_version/up.sql @@ -1,4 +1,7 @@ -- Add Software and Version columns from nodeinfo to the instance table +ALTER TABLE instance + ADD COLUMN software varchar(255); + +ALTER TABLE instance + ADD COLUMN version varchar(255); -alter table instance add column software varchar(255); -alter table instance add column version varchar(255); diff --git a/migrations/2023-02-15-212546_add_post_comment_saved_indexes/down.sql b/migrations/2023-02-15-212546_add_post_comment_saved_indexes/down.sql index 3ef1500c..bd9b6bba 100644 --- a/migrations/2023-02-15-212546_add_post_comment_saved_indexes/down.sql +++ b/migrations/2023-02-15-212546_add_post_comment_saved_indexes/down.sql @@ -1 +1,2 @@ -drop index idx_post_saved_person_id, idx_comment_saved_person_id; +DROP INDEX idx_post_saved_person_id, idx_comment_saved_person_id; + diff --git a/migrations/2023-02-15-212546_add_post_comment_saved_indexes/up.sql b/migrations/2023-02-15-212546_add_post_comment_saved_indexes/up.sql index 88994312..98db2779 100644 --- a/migrations/2023-02-15-212546_add_post_comment_saved_indexes/up.sql +++ b/migrations/2023-02-15-212546_add_post_comment_saved_indexes/up.sql @@ -1,2 +1,4 @@ -create index idx_post_saved_person_id on post_saved (person_id); -create index idx_comment_saved_person_id on comment_saved (person_id); +CREATE INDEX idx_post_saved_person_id ON post_saved (person_id); + +CREATE INDEX idx_comment_saved_person_id ON comment_saved (person_id); + diff --git a/migrations/2023-02-16-194139_add_totp_secret/down.sql b/migrations/2023-02-16-194139_add_totp_secret/down.sql index b7f38c45..7adf97e6 100644 --- a/migrations/2023-02-16-194139_add_totp_secret/down.sql +++ b/migrations/2023-02-16-194139_add_totp_secret/down.sql @@ -1,2 +1,6 @@ -alter table local_user drop column totp_2fa_secret; -alter table local_user drop column totp_2fa_url; +ALTER TABLE local_user + DROP COLUMN totp_2fa_secret; + +ALTER TABLE local_user + DROP COLUMN totp_2fa_url; + diff --git a/migrations/2023-02-16-194139_add_totp_secret/up.sql b/migrations/2023-02-16-194139_add_totp_secret/up.sql index e40c1c66..43ff8dc9 100644 --- a/migrations/2023-02-16-194139_add_totp_secret/up.sql +++ b/migrations/2023-02-16-194139_add_totp_secret/up.sql @@ -1,2 +1,6 @@ -alter table local_user add column totp_2fa_secret text; -alter table local_user add column totp_2fa_url text; +ALTER TABLE local_user + ADD COLUMN totp_2fa_secret text; + +ALTER TABLE local_user + ADD COLUMN totp_2fa_url text; + diff --git a/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/down.sql b/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/down.sql index 5d5f2f3a..ceb36f53 100644 --- a/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/down.sql +++ b/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/down.sql @@ -1,62 +1,126 @@ -- Some fixes -alter table community alter column hidden drop not null; -alter table community alter column posting_restricted_to_mods drop not null; -alter table activity alter column sensitive drop not null; -alter table mod_add alter column removed drop not null; -alter table mod_add_community alter column removed drop not null; -alter table mod_ban alter column banned drop not null; -alter table mod_ban_from_community alter column banned drop not null; -alter table mod_hide_community alter column hidden drop not null; -alter table mod_lock_post alter column locked drop not null; -alter table mod_remove_comment alter column removed drop not null; -alter table mod_remove_community alter column removed drop not null; -alter table mod_remove_post alter column removed drop not null; -alter table mod_transfer_community add column removed boolean default false; -alter table language alter column code drop not null; -alter table language alter column name drop not null; +ALTER TABLE community + ALTER COLUMN hidden DROP NOT NULL; + +ALTER TABLE community + ALTER COLUMN posting_restricted_to_mods DROP NOT NULL; + +ALTER TABLE activity + ALTER COLUMN sensitive DROP NOT NULL; + +ALTER TABLE mod_add + ALTER COLUMN removed DROP NOT NULL; + +ALTER TABLE mod_add_community + ALTER COLUMN removed DROP NOT NULL; + +ALTER TABLE mod_ban + ALTER COLUMN banned DROP NOT NULL; + +ALTER TABLE mod_ban_from_community + ALTER COLUMN banned DROP NOT NULL; + +ALTER TABLE mod_hide_community + ALTER COLUMN hidden DROP NOT NULL; + +ALTER TABLE mod_lock_post + ALTER COLUMN LOCKED DROP NOT NULL; + +ALTER TABLE mod_remove_comment + ALTER COLUMN removed DROP NOT NULL; + +ALTER TABLE mod_remove_community + ALTER COLUMN removed DROP NOT NULL; + +ALTER TABLE mod_remove_post + ALTER COLUMN removed DROP NOT NULL; + +ALTER TABLE mod_transfer_community + ADD COLUMN removed boolean DEFAULT FALSE; + +ALTER TABLE LANGUAGE + ALTER COLUMN code DROP NOT NULL; + +ALTER TABLE LANGUAGE + ALTER COLUMN name DROP NOT NULL; -- Fix the registration mode enums ALTER TYPE registration_mode_enum RENAME VALUE 'Closed' TO 'closed'; + ALTER TYPE registration_mode_enum RENAME VALUE 'RequireApplication' TO 'require_application'; + ALTER TYPE registration_mode_enum RENAME VALUE 'Open' TO 'open'; -- add back old columns - -- Alter the local_user table -alter table local_user alter column default_sort_type drop default; -alter table local_user alter column default_sort_type type smallint using - case default_sort_type - when 'Active' then 0 - when 'Hot' then 1 - when 'New' then 2 - when 'Old' then 3 - when 'TopDay' then 4 - when 'TopWeek' then 5 - when 'TopMonth' then 6 - when 'TopYear' then 7 - when 'TopAll' then 8 - when 'MostComments' then 9 - when 'NewComments' then 10 - else 0 - end; -alter table local_user alter column default_sort_type set default 0; - -alter table local_user alter column default_listing_type drop default; -alter table local_user alter column default_listing_type type smallint using - case default_listing_type - when 'All' then 0 - when 'Local' then 1 - when 'Subscribed' then 2 - else 1 - end; -alter table local_user alter column default_listing_type set default 1; +ALTER TABLE local_user + ALTER COLUMN default_sort_type DROP DEFAULT; + +ALTER TABLE local_user + ALTER COLUMN default_sort_type TYPE smallint + USING + CASE default_sort_type + WHEN 'Active' THEN + 0 + WHEN 'Hot' THEN + 1 + WHEN 'New' THEN + 2 + WHEN 'Old' THEN + 3 + WHEN 'TopDay' THEN + 4 + WHEN 'TopWeek' THEN + 5 + WHEN 'TopMonth' THEN + 6 + WHEN 'TopYear' THEN + 7 + WHEN 'TopAll' THEN + 8 + WHEN 'MostComments' THEN + 9 + WHEN 'NewComments' THEN + 10 + ELSE + 0 + END; + +ALTER TABLE local_user + ALTER COLUMN default_sort_type SET DEFAULT 0; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type DROP DEFAULT; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type TYPE smallint + USING + CASE default_listing_type + WHEN 'All' THEN + 0 + WHEN 'Local' THEN + 1 + WHEN 'Subscribed' THEN + 2 + ELSE + 1 + END; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type SET DEFAULT 1; -- Alter the local site column +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type DROP DEFAULT; -alter table local_site alter column default_post_listing_type drop default; -alter table local_site alter column default_post_listing_type type text; -alter table local_site alter column default_post_listing_type set default 1; +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type TYPE text; + +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type SET DEFAULT 1; -- Drop the types -drop type listing_type_enum; -drop type sort_type_enum; +DROP TYPE listing_type_enum; + +DROP TYPE sort_type_enum; + diff --git a/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/up.sql b/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/up.sql index 8474f34e..bfce9a6a 100644 --- a/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/up.sql +++ b/migrations/2023-04-14-175955_add_listingtype_sorttype_enums/up.sql @@ -1,61 +1,142 @@ -- A few DB fixes -alter table community alter column hidden set not null; -alter table community alter column posting_restricted_to_mods set not null; -alter table activity alter column sensitive set not null; -alter table mod_add alter column removed set not null; -alter table mod_add_community alter column removed set not null; -alter table mod_ban alter column banned set not null; -alter table mod_ban_from_community alter column banned set not null; -alter table mod_hide_community alter column hidden set not null; -alter table mod_lock_post alter column locked set not null; -alter table mod_remove_comment alter column removed set not null; -alter table mod_remove_community alter column removed set not null; -alter table mod_remove_post alter column removed set not null; -alter table mod_transfer_community drop column removed; -alter table language alter column code set not null; -alter table language alter column name set not null; +ALTER TABLE community + ALTER COLUMN hidden SET NOT NULL; + +ALTER TABLE community + ALTER COLUMN posting_restricted_to_mods SET NOT NULL; + +ALTER TABLE activity + ALTER COLUMN sensitive SET NOT NULL; + +ALTER TABLE mod_add + ALTER COLUMN removed SET NOT NULL; + +ALTER TABLE mod_add_community + ALTER COLUMN removed SET NOT NULL; + +ALTER TABLE mod_ban + ALTER COLUMN banned SET NOT NULL; + +ALTER TABLE mod_ban_from_community + ALTER COLUMN banned SET NOT NULL; + +ALTER TABLE mod_hide_community + ALTER COLUMN hidden SET NOT NULL; + +ALTER TABLE mod_lock_post + ALTER COLUMN LOCKED SET NOT NULL; + +ALTER TABLE mod_remove_comment + ALTER COLUMN removed SET NOT NULL; + +ALTER TABLE mod_remove_community + ALTER COLUMN removed SET NOT NULL; + +ALTER TABLE mod_remove_post + ALTER COLUMN removed SET NOT NULL; + +ALTER TABLE mod_transfer_community + DROP COLUMN removed; + +ALTER TABLE LANGUAGE + ALTER COLUMN code SET NOT NULL; + +ALTER TABLE LANGUAGE + ALTER COLUMN name SET NOT NULL; -- Fix the registration mode enums ALTER TYPE registration_mode_enum RENAME VALUE 'closed' TO 'Closed'; + ALTER TYPE registration_mode_enum RENAME VALUE 'require_application' TO 'RequireApplication'; + ALTER TYPE registration_mode_enum RENAME VALUE 'open' TO 'Open'; -- Create the enums +CREATE TYPE sort_type_enum AS ENUM ( + 'Active', + 'Hot', + 'New', + 'Old', + 'TopDay', + 'TopWeek', + 'TopMonth', + 'TopYear', + 'TopAll', + 'MostComments', + 'NewComments' +); -CREATE TYPE sort_type_enum AS ENUM ('Active', 'Hot', 'New', 'Old', 'TopDay', 'TopWeek', 'TopMonth', 'TopYear', 'TopAll', 'MostComments', 'NewComments'); - -CREATE TYPE listing_type_enum AS ENUM ('All', 'Local', 'Subscribed'); +CREATE TYPE listing_type_enum AS ENUM ( + 'All', + 'Local', + 'Subscribed' +); -- Alter the local_user table -alter table local_user alter column default_sort_type drop default; -alter table local_user alter column default_sort_type type sort_type_enum using - case default_sort_type - when 0 then 'Active' - when 1 then 'Hot' - when 2 then 'New' - when 3 then 'Old' - when 4 then 'TopDay' - when 5 then 'TopWeek' - when 6 then 'TopMonth' - when 7 then 'TopYear' - when 8 then 'TopAll' - when 9 then 'MostComments' - when 10 then 'NewComments' - else 'Active' - end :: sort_type_enum; -alter table local_user alter column default_sort_type set default 'Active'; - -alter table local_user alter column default_listing_type drop default; -alter table local_user alter column default_listing_type type listing_type_enum using - case default_listing_type - when 0 then 'All' - when 1 then 'Local' - when 2 then 'Subscribed' - else 'Local' - end :: listing_type_enum; -alter table local_user alter column default_listing_type set default 'Local'; +ALTER TABLE local_user + ALTER COLUMN default_sort_type DROP DEFAULT; + +ALTER TABLE local_user + ALTER COLUMN default_sort_type TYPE sort_type_enum + USING + CASE default_sort_type + WHEN 0 THEN + 'Active' + WHEN 1 THEN + 'Hot' + WHEN 2 THEN + 'New' + WHEN 3 THEN + 'Old' + WHEN 4 THEN + 'TopDay' + WHEN 5 THEN + 'TopWeek' + WHEN 6 THEN + 'TopMonth' + WHEN 7 THEN + 'TopYear' + WHEN 8 THEN + 'TopAll' + WHEN 9 THEN + 'MostComments' + WHEN 10 THEN + 'NewComments' + ELSE + 'Active' + END::sort_type_enum; + +ALTER TABLE local_user + ALTER COLUMN default_sort_type SET DEFAULT 'Active'; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type DROP DEFAULT; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type TYPE listing_type_enum + USING + CASE default_listing_type + WHEN 0 THEN + 'All' + WHEN 1 THEN + 'Local' + WHEN 2 THEN + 'Subscribed' + ELSE + 'Local' + END::listing_type_enum; + +ALTER TABLE local_user + ALTER COLUMN default_listing_type SET DEFAULT 'Local'; -- Alter the local site column -alter table local_site alter column default_post_listing_type drop default; -alter table local_site alter column default_post_listing_type type listing_type_enum using default_post_listing_type::listing_type_enum; -alter table local_site alter column default_post_listing_type set default 'Local'; +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type DROP DEFAULT; + +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type TYPE listing_type_enum + USING default_post_listing_type::listing_type_enum; + +ALTER TABLE local_site + ALTER COLUMN default_post_listing_type SET DEFAULT 'Local'; + diff --git a/migrations/2023-04-23-164732_add_person_details_indexes/down.sql b/migrations/2023-04-23-164732_add_person_details_indexes/down.sql index 67879de4..d32b21ec 100644 --- a/migrations/2023-04-23-164732_add_person_details_indexes/down.sql +++ b/migrations/2023-04-23-164732_add_person_details_indexes/down.sql @@ -1,21 +1,42 @@ -drop index idx_person_lower_name; -drop index idx_community_lower_name; -drop index idx_community_moderator_published; -drop index idx_community_moderator_community; -drop index idx_community_moderator_person; -drop index idx_comment_saved_comment; -drop index idx_comment_saved_person; -drop index idx_community_block_community; -drop index idx_community_block_person; -drop index idx_community_follower_community; -drop index idx_community_follower_person; -drop index idx_person_block_person; -drop index idx_person_block_target; -drop index idx_post_language; -drop index idx_comment_language; -drop index idx_person_aggregates_person; -drop index idx_person_post_aggregates_post; -drop index idx_person_post_aggregates_person; -drop index idx_comment_reply_comment; -drop index idx_comment_reply_recipient; -drop index idx_comment_reply_published; \ No newline at end of file +DROP INDEX idx_person_lower_name; + +DROP INDEX idx_community_lower_name; + +DROP INDEX idx_community_moderator_published; + +DROP INDEX idx_community_moderator_community; + +DROP INDEX idx_community_moderator_person; + +DROP INDEX idx_comment_saved_comment; + +DROP INDEX idx_comment_saved_person; + +DROP INDEX idx_community_block_community; + +DROP INDEX idx_community_block_person; + +DROP INDEX idx_community_follower_community; + +DROP INDEX idx_community_follower_person; + +DROP INDEX idx_person_block_person; + +DROP INDEX idx_person_block_target; + +DROP INDEX idx_post_language; + +DROP INDEX idx_comment_language; + +DROP INDEX idx_person_aggregates_person; + +DROP INDEX idx_person_post_aggregates_post; + +DROP INDEX idx_person_post_aggregates_person; + +DROP INDEX idx_comment_reply_comment; + +DROP INDEX idx_comment_reply_recipient; + +DROP INDEX idx_comment_reply_published; + diff --git a/migrations/2023-04-23-164732_add_person_details_indexes/up.sql b/migrations/2023-04-23-164732_add_person_details_indexes/up.sql index df3dde7e..c6a340f1 100644 --- a/migrations/2023-04-23-164732_add_person_details_indexes/up.sql +++ b/migrations/2023-04-23-164732_add_person_details_indexes/up.sql @@ -1,31 +1,43 @@ -- Add a few indexes to speed up person details queries -create index idx_person_lower_name on person (lower(name)); -create index idx_community_lower_name on community (lower(name)); +CREATE INDEX idx_person_lower_name ON person (lower(name)); -create index idx_community_moderator_published on community_moderator (published); -create index idx_community_moderator_community on community_moderator (community_id); -create index idx_community_moderator_person on community_moderator (person_id); +CREATE INDEX idx_community_lower_name ON community (lower(name)); -create index idx_comment_saved_comment on comment_saved (comment_id); -create index idx_comment_saved_person on comment_saved (person_id); +CREATE INDEX idx_community_moderator_published ON community_moderator (published); -create index idx_community_block_community on community_block (community_id); -create index idx_community_block_person on community_block (person_id); +CREATE INDEX idx_community_moderator_community ON community_moderator (community_id); -create index idx_community_follower_community on community_follower (community_id); -create index idx_community_follower_person on community_follower (person_id); +CREATE INDEX idx_community_moderator_person ON community_moderator (person_id); -create index idx_person_block_person on person_block (person_id); -create index idx_person_block_target on person_block (target_id); +CREATE INDEX idx_comment_saved_comment ON comment_saved (comment_id); -create index idx_post_language on post (language_id); -create index idx_comment_language on comment (language_id); +CREATE INDEX idx_comment_saved_person ON comment_saved (person_id); -create index idx_person_aggregates_person on person_aggregates (person_id); +CREATE INDEX idx_community_block_community ON community_block (community_id); -create index idx_person_post_aggregates_post on person_post_aggregates (post_id); -create index idx_person_post_aggregates_person on person_post_aggregates (person_id); +CREATE INDEX idx_community_block_person ON community_block (person_id); + +CREATE INDEX idx_community_follower_community ON community_follower (community_id); + +CREATE INDEX idx_community_follower_person ON community_follower (person_id); + +CREATE INDEX idx_person_block_person ON person_block (person_id); + +CREATE INDEX idx_person_block_target ON person_block (target_id); + +CREATE INDEX idx_post_language ON post (language_id); + +CREATE INDEX idx_comment_language ON comment (language_id); + +CREATE INDEX idx_person_aggregates_person ON person_aggregates (person_id); + +CREATE INDEX idx_person_post_aggregates_post ON person_post_aggregates (post_id); + +CREATE INDEX idx_person_post_aggregates_person ON person_post_aggregates (person_id); + +CREATE INDEX idx_comment_reply_comment ON comment_reply (comment_id); + +CREATE INDEX idx_comment_reply_recipient ON comment_reply (recipient_id); + +CREATE INDEX idx_comment_reply_published ON comment_reply (published DESC); -create index idx_comment_reply_comment on comment_reply (comment_id); -create index idx_comment_reply_recipient on comment_reply (recipient_id); -create index idx_comment_reply_published on comment_reply (published desc); diff --git a/migrations/2023-05-10-095739_force_enable_undetermined_language/up.sql b/migrations/2023-05-10-095739_force_enable_undetermined_language/up.sql index b320ecad..8b501d5b 100644 --- a/migrations/2023-05-10-095739_force_enable_undetermined_language/up.sql +++ b/migrations/2023-05-10-095739_force_enable_undetermined_language/up.sql @@ -1,4 +1,11 @@ -- force enable undetermined language for all users -insert into local_user_language (local_user_id, language_id) - select id, 0 from local_user - on conflict (local_user_id, language_id) do nothing; +INSERT INTO local_user_language (local_user_id, language_id) +SELECT + id, + 0 +FROM + local_user +ON CONFLICT (local_user_id, + language_id) + DO NOTHING; + diff --git a/migrations/2023-06-06-104440_index_post_url/down.sql b/migrations/2023-06-06-104440_index_post_url/down.sql index ccc9e938..7ddea79c 100644 --- a/migrations/2023-06-06-104440_index_post_url/down.sql +++ b/migrations/2023-06-06-104440_index_post_url/down.sql @@ -1,5 +1,7 @@ -- Change back the column type -alter table post alter column url type text; +ALTER TABLE post + ALTER COLUMN url TYPE text; -- Drop the index -drop index idx_post_url; +DROP INDEX idx_post_url; + diff --git a/migrations/2023-06-06-104440_index_post_url/up.sql b/migrations/2023-06-06-104440_index_post_url/up.sql index ce353288..5e0f1146 100644 --- a/migrations/2023-06-06-104440_index_post_url/up.sql +++ b/migrations/2023-06-06-104440_index_post_url/up.sql @@ -1,9 +1,18 @@ -- Make a hard limit of 512 for the post.url column -- Truncate existing long rows. -update post set url = left(url, 512) where length(url) > 512; +UPDATE + post +SET + url = + LEFT (url, + 512) +WHERE + length(url) > 512; -- Enforce the limit -alter table post alter column url type varchar (512); +ALTER TABLE post + ALTER COLUMN url TYPE varchar(512); -- Add the index -create index idx_post_url on post(url); +CREATE INDEX idx_post_url ON post (url); + diff --git a/migrations/2023-06-07-105918_add_hot_rank_columns/down.sql b/migrations/2023-06-07-105918_add_hot_rank_columns/down.sql index 71529bdf..e82fdff3 100644 --- a/migrations/2023-06-07-105918_add_hot_rank_columns/down.sql +++ b/migrations/2023-06-07-105918_add_hot_rank_columns/down.sql @@ -1,35 +1,55 @@ - -- Remove the new columns +ALTER TABLE post_aggregates + DROP COLUMN hot_rank; -alter table post_aggregates drop column hot_rank; -alter table post_aggregates drop column hot_rank_active; +ALTER TABLE post_aggregates + DROP COLUMN hot_rank_active; -alter table comment_aggregates drop column hot_rank; +ALTER TABLE comment_aggregates + DROP COLUMN hot_rank; -alter table community_aggregates drop column hot_rank; +ALTER TABLE community_aggregates + DROP COLUMN hot_rank; -- Drop some new indexes -drop index idx_post_aggregates_score; -drop index idx_post_aggregates_published; -drop index idx_post_aggregates_newest_comment_time; -drop index idx_post_aggregates_newest_comment_time_necro; -drop index idx_post_aggregates_featured_community; -drop index idx_post_aggregates_featured_local; +DROP INDEX idx_post_aggregates_score; + +DROP INDEX idx_post_aggregates_published; + +DROP INDEX idx_post_aggregates_newest_comment_time; + +DROP INDEX idx_post_aggregates_newest_comment_time_necro; + +DROP INDEX idx_post_aggregates_featured_community; + +DROP INDEX idx_post_aggregates_featured_local; -- Recreate the old indexes CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time ON public.post_aggregates USING btree (featured_local DESC, newest_comment_time DESC); + CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time ON public.post_aggregates USING btree (featured_community DESC, newest_comment_time DESC); + CREATE INDEX idx_post_aggregates_featured_local_comments ON public.post_aggregates USING btree (featured_local DESC, comments DESC); + CREATE INDEX idx_post_aggregates_featured_community_comments ON public.post_aggregates USING btree (featured_community DESC, comments DESC); -CREATE INDEX idx_post_aggregates_featured_local_hot ON public.post_aggregates USING btree (featured_local DESC, hot_rank((score)::numeric, published) DESC, published DESC); -CREATE INDEX idx_post_aggregates_featured_community_hot ON public.post_aggregates USING btree (featured_community DESC, hot_rank((score)::numeric, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_local_hot ON public.post_aggregates USING btree (featured_local DESC, hot_rank ((score)::numeric, published) DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_community_hot ON public.post_aggregates USING btree (featured_community DESC, hot_rank ((score)::numeric, published) DESC, published DESC); + CREATE INDEX idx_post_aggregates_featured_local_score ON public.post_aggregates USING btree (featured_local DESC, score DESC); + CREATE INDEX idx_post_aggregates_featured_community_score ON public.post_aggregates USING btree (featured_community DESC, score DESC); + CREATE INDEX idx_post_aggregates_featured_local_published ON public.post_aggregates USING btree (featured_local DESC, published DESC); + CREATE INDEX idx_post_aggregates_featured_community_published ON public.post_aggregates USING btree (featured_community DESC, published DESC); -CREATE INDEX idx_post_aggregates_featured_local_active ON public.post_aggregates USING btree (featured_local DESC, hot_rank((score)::numeric, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); -CREATE INDEX idx_post_aggregates_featured_community_active ON public.post_aggregates USING btree (featured_community DESC, hot_rank((score)::numeric, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); -CREATE INDEX idx_comment_aggregates_hot ON public.comment_aggregates USING btree (hot_rank((score)::numeric, published) DESC, published DESC); +CREATE INDEX idx_post_aggregates_featured_local_active ON public.post_aggregates USING btree (featured_local DESC, hot_rank ((score)::numeric, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON public.post_aggregates USING btree (featured_community DESC, hot_rank ((score)::numeric, newest_comment_time_necro) DESC, newest_comment_time_necro DESC); + +CREATE INDEX idx_comment_aggregates_hot ON public.comment_aggregates USING btree (hot_rank ((score)::numeric, published) DESC, published DESC); + +CREATE INDEX idx_community_aggregates_hot ON public.community_aggregates USING btree (hot_rank ((subscribers)::numeric, published) DESC, published DESC); -CREATE INDEX idx_community_aggregates_hot ON public.community_aggregates USING btree (hot_rank((subscribers)::numeric, published) DESC, published DESC); diff --git a/migrations/2023-06-07-105918_add_hot_rank_columns/up.sql b/migrations/2023-06-07-105918_add_hot_rank_columns/up.sql index 92f03e5f..00c8fae2 100644 --- a/migrations/2023-06-07-105918_add_hot_rank_columns/up.sql +++ b/migrations/2023-06-07-105918_add_hot_rank_columns/up.sql @@ -1,17 +1,27 @@ -- This converts the old hot_rank functions, to columns - -- Remove the old compound indexes DROP INDEX idx_post_aggregates_featured_local_newest_comment_time; + DROP INDEX idx_post_aggregates_featured_community_newest_comment_time; + DROP INDEX idx_post_aggregates_featured_local_comments; + DROP INDEX idx_post_aggregates_featured_community_comments; + DROP INDEX idx_post_aggregates_featured_local_hot; + DROP INDEX idx_post_aggregates_featured_community_hot; + DROP INDEX idx_post_aggregates_featured_local_score; + DROP INDEX idx_post_aggregates_featured_community_score; + DROP INDEX idx_post_aggregates_featured_local_published; + DROP INDEX idx_post_aggregates_featured_community_published; + DROP INDEX idx_post_aggregates_featured_local_active; + DROP INDEX idx_post_aggregates_featured_community_active; DROP INDEX idx_comment_aggregates_hot; @@ -21,31 +31,59 @@ DROP INDEX idx_community_aggregates_hot; -- Add the new hot rank columns for post and comment aggregates -- Note: 1728 is the result of the hot_rank function, with a score of 1, posted now -- hot_rank = 10000*log10(1 + 3)/Power(2, 1.8) -alter table post_aggregates add column hot_rank integer not null default 1728; -alter table post_aggregates add column hot_rank_active integer not null default 1728; +ALTER TABLE post_aggregates + ADD COLUMN hot_rank integer NOT NULL DEFAULT 1728; + +ALTER TABLE post_aggregates + ADD COLUMN hot_rank_active integer NOT NULL DEFAULT 1728; -alter table comment_aggregates add column hot_rank integer not null default 1728; +ALTER TABLE comment_aggregates + ADD COLUMN hot_rank integer NOT NULL DEFAULT 1728; -alter table community_aggregates add column hot_rank integer not null default 1728; +ALTER TABLE community_aggregates + ADD COLUMN hot_rank integer NOT NULL DEFAULT 1728; -- Populate them initially --- Note: After initial population, these are updated in a periodic scheduled job, +-- Note: After initial population, these are updated in a periodic scheduled job, -- with only the last week being updated. -update post_aggregates set hot_rank_active = hot_rank(score::numeric, newest_comment_time_necro); -update post_aggregates set hot_rank = hot_rank(score::numeric, published); -update comment_aggregates set hot_rank = hot_rank(score::numeric, published); -update community_aggregates set hot_rank = hot_rank(subscribers::numeric, published); +UPDATE + post_aggregates +SET + hot_rank_active = hot_rank (score::numeric, newest_comment_time_necro); + +UPDATE + post_aggregates +SET + hot_rank = hot_rank (score::numeric, published); + +UPDATE + comment_aggregates +SET + hot_rank = hot_rank (score::numeric, published); + +UPDATE + community_aggregates +SET + hot_rank = hot_rank (subscribers::numeric, published); -- Create single column indexes -create index idx_post_aggregates_score on post_aggregates (score desc); -create index idx_post_aggregates_published on post_aggregates (published desc); -create index idx_post_aggregates_newest_comment_time on post_aggregates (newest_comment_time desc); -create index idx_post_aggregates_newest_comment_time_necro on post_aggregates (newest_comment_time_necro desc); -create index idx_post_aggregates_featured_community on post_aggregates (featured_community desc); -create index idx_post_aggregates_featured_local on post_aggregates (featured_local desc); -create index idx_post_aggregates_hot on post_aggregates (hot_rank desc); -create index idx_post_aggregates_active on post_aggregates (hot_rank_active desc); - -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank desc); - -create index idx_community_aggregates_hot on community_aggregates (hot_rank desc); +CREATE INDEX idx_post_aggregates_score ON post_aggregates (score DESC); + +CREATE INDEX idx_post_aggregates_published ON post_aggregates (published DESC); + +CREATE INDEX idx_post_aggregates_newest_comment_time ON post_aggregates (newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_newest_comment_time_necro ON post_aggregates (newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_community ON post_aggregates (featured_community DESC); + +CREATE INDEX idx_post_aggregates_featured_local ON post_aggregates (featured_local DESC); + +CREATE INDEX idx_post_aggregates_hot ON post_aggregates (hot_rank DESC); + +CREATE INDEX idx_post_aggregates_active ON post_aggregates (hot_rank_active DESC); + +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank DESC); + +CREATE INDEX idx_community_aggregates_hot ON community_aggregates (hot_rank DESC); + diff --git a/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/down.sql b/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/down.sql index 006bb108..bdf20b8e 100644 --- a/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/down.sql +++ b/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/down.sql @@ -1,14 +1,34 @@ -- update the default sort type -update local_user set default_sort_type = 'TopDay' where default_sort_type in ('TopHour', 'TopSixHour', 'TopTwelveHour'); +UPDATE + local_user +SET + default_sort_type = 'TopDay' +WHERE + default_sort_type IN ('TopHour', 'TopSixHour', 'TopTwelveHour'); -- rename the old enum -alter type sort_type_enum rename to sort_type_enum__; +ALTER TYPE sort_type_enum RENAME TO sort_type_enum__; + -- create the new enum -CREATE TYPE sort_type_enum AS ENUM ('Active', 'Hot', 'New', 'Old', 'TopDay', 'TopWeek', 'TopMonth', 'TopYear', 'TopAll', 'MostComments', 'NewComments'); +CREATE TYPE sort_type_enum AS ENUM ( + 'Active', + 'Hot', + 'New', + 'Old', + 'TopDay', + 'TopWeek', + 'TopMonth', + 'TopYear', + 'TopAll', + 'MostComments', + 'NewComments' +); -- alter all you enum columns -alter table local_user - alter column default_sort_type type sort_type_enum using default_sort_type::text::sort_type_enum; +ALTER TABLE local_user + ALTER COLUMN default_sort_type TYPE sort_type_enum + USING default_sort_type::text::sort_type_enum; -- drop the old enum -drop type sort_type_enum__; \ No newline at end of file +DROP TYPE sort_type_enum__; + diff --git a/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/up.sql b/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/up.sql index 7e4b6fbd..2068269e 100644 --- a/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/up.sql +++ b/migrations/2023-06-17-175955_add_listingtype_sorttype_hour_enums/up.sql @@ -1,4 +1,10 @@ -- Update the enums -ALTER TYPE sort_type_enum ADD VALUE 'TopHour'; -ALTER TYPE sort_type_enum ADD VALUE 'TopSixHour'; -ALTER TYPE sort_type_enum ADD VALUE 'TopTwelveHour'; \ No newline at end of file +ALTER TYPE sort_type_enum + ADD VALUE 'TopHour'; + +ALTER TYPE sort_type_enum + ADD VALUE 'TopSixHour'; + +ALTER TYPE sort_type_enum + ADD VALUE 'TopTwelveHour'; + diff --git a/migrations/2023-06-19-055530_add_retry_worker_setting/down.sql b/migrations/2023-06-19-055530_add_retry_worker_setting/down.sql index e3c200a1..948d044f 100644 --- a/migrations/2023-06-19-055530_add_retry_worker_setting/down.sql +++ b/migrations/2023-06-19-055530_add_retry_worker_setting/down.sql @@ -1 +1,3 @@ -alter table local_site add column federation_worker_count int default 64 not null; \ No newline at end of file +ALTER TABLE local_site + ADD COLUMN federation_worker_count int DEFAULT 64 NOT NULL; + diff --git a/migrations/2023-06-19-055530_add_retry_worker_setting/up.sql b/migrations/2023-06-19-055530_add_retry_worker_setting/up.sql index 2aac86f8..e4eb058e 100644 --- a/migrations/2023-06-19-055530_add_retry_worker_setting/up.sql +++ b/migrations/2023-06-19-055530_add_retry_worker_setting/up.sql @@ -1 +1,3 @@ -alter table local_site drop column federation_worker_count; \ No newline at end of file +ALTER TABLE local_site + DROP COLUMN federation_worker_count; + diff --git a/migrations/2023-06-19-120700_no_double_deletion/down.sql b/migrations/2023-06-19-120700_no_double_deletion/down.sql index 94727802..aec7c653 100644 --- a/migrations/2023-06-19-120700_no_double_deletion/down.sql +++ b/migrations/2023-06-19-120700_no_double_deletion/down.sql @@ -1,19 +1,20 @@ -- This file should undo anything in `up.sql` -create or replace function was_removed_or_deleted(TG_OP text, OLD record, NEW record) -RETURNS boolean -LANGUAGE plpgsql -as $$ - begin - IF (TG_OP = 'INSERT') THEN - return false; - end if; +CREATE OR REPLACE FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + RETURN FALSE; + END IF; + IF (TG_OP = 'DELETE') THEN + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 'f' + AND NEW.deleted = 't') + OR (OLD.removed = 'f' + AND NEW.removed = 't')); +END +$$; - IF (TG_OP = 'DELETE') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 'f' AND NEW.deleted = 't') OR - (OLD.removed = 'f' AND NEW.removed = 't') - ); -END $$; diff --git a/migrations/2023-06-19-120700_no_double_deletion/up.sql b/migrations/2023-06-19-120700_no_double_deletion/up.sql index bd6d1e58..38ab5c7b 100644 --- a/migrations/2023-06-19-120700_no_double_deletion/up.sql +++ b/migrations/2023-06-19-120700_no_double_deletion/up.sql @@ -1,67 +1,100 @@ -- Deleting after removing should not decrement the count twice. -create or replace function was_removed_or_deleted(TG_OP text, OLD record, NEW record) -RETURNS boolean -LANGUAGE plpgsql -as $$ - begin - IF (TG_OP = 'INSERT') THEN - return false; - end if; - - IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 'f' AND NEW.deleted = 't') OR - (OLD.removed = 'f' AND NEW.removed = 't') - ); -END $$; +CREATE OR REPLACE FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + RETURN FALSE; + END IF; + IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 'f' + AND NEW.deleted = 't') + OR (OLD.removed = 'f' + AND NEW.removed = 't')); +END +$$; -- Recalculate proper comment count. -UPDATE person_aggregates - SET comment_count = cnt.count - FROM ( - SELECT creator_id, count(*) AS count FROM comment - WHERE deleted='f' AND removed='f' - GROUP BY creator_id - ) cnt - WHERE person_aggregates.person_id = cnt.creator_id; +UPDATE + person_aggregates +SET + comment_count = cnt.count +FROM ( + SELECT + creator_id, + count(*) AS count + FROM + comment + WHERE + deleted = 'f' + AND removed = 'f' + GROUP BY + creator_id) cnt +WHERE + person_aggregates.person_id = cnt.creator_id; -- Recalculate proper comment score. -UPDATE person_aggregates ua - SET comment_score = cd.score - FROM ( - SELECT u.id AS creator_id, - coalesce(0, sum(cl.score)) as score +UPDATE + person_aggregates ua +SET + comment_score = cd.score +FROM ( + SELECT + u.id AS creator_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 AND c.deleted = 'f' AND c.removed = 'f' - LEFT JOIN comment_like cl ON c.id = cl.comment_id - GROUP BY u.id - ) cd - WHERE ua.person_id = cd.creator_id; + FROM + person u + LEFT JOIN comment c ON u.id = c.creator_id + AND c.deleted = 'f' + AND c.removed = 'f' + LEFT JOIN comment_like cl ON c.id = cl.comment_id +GROUP BY + u.id) cd +WHERE + ua.person_id = cd.creator_id; -- Recalculate proper post count. -UPDATE person_aggregates - SET post_count = cnt.count - FROM ( - SELECT creator_id, count(*) AS count FROM post - WHERE deleted='f' AND removed='f' - GROUP BY creator_id - ) cnt - WHERE person_aggregates.person_id = cnt.creator_id; +UPDATE + person_aggregates +SET + post_count = cnt.count +FROM ( + SELECT + creator_id, + count(*) AS count + FROM + post + WHERE + deleted = 'f' + AND removed = 'f' + GROUP BY + creator_id) cnt +WHERE + person_aggregates.person_id = cnt.creator_id; -- Recalculate proper post score. - UPDATE person_aggregates ua - SET post_score = pd.score - FROM ( - SELECT u.id AS creator_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 AND p.deleted = 'f' AND p.removed = 'f' - LEFT JOIN post_like pl ON p.id = pl.post_id - GROUP BY u.id - ) pd - WHERE ua.person_id = pd.creator_id; +UPDATE + person_aggregates ua +SET + post_score = pd.score +FROM ( + SELECT + u.id AS creator_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 + AND p.deleted = 'f' + AND p.removed = 'f' + LEFT JOIN post_like pl ON p.id = pl.post_id +GROUP BY + u.id) pd +WHERE + ua.person_id = pd.creator_id; + diff --git a/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/down.sql b/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/down.sql index 5b135223..694b62ee 100644 --- a/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/down.sql +++ b/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/down.sql @@ -1,14 +1,37 @@ -- update the default sort type -update local_user set default_sort_type = 'TopDay' where default_sort_type in ('TopThreeMonths', 'TopSixMonths', 'TopNineMonths'); +UPDATE + local_user +SET + default_sort_type = 'TopDay' +WHERE + default_sort_type IN ('TopThreeMonths', 'TopSixMonths', 'TopNineMonths'); -- rename the old enum -alter type sort_type_enum rename to sort_type_enum__; +ALTER TYPE sort_type_enum RENAME TO sort_type_enum__; + -- create the new enum -CREATE TYPE sort_type_enum AS ENUM ('Active', 'Hot', 'New', 'Old', 'TopDay', 'TopWeek', 'TopMonth', 'TopYear', 'TopAll', 'MostComments', 'NewComments', 'TopHour', 'TopSixHour', 'TopTwelveHour'); +CREATE TYPE sort_type_enum AS ENUM ( + 'Active', + 'Hot', + 'New', + 'Old', + 'TopDay', + 'TopWeek', + 'TopMonth', + 'TopYear', + 'TopAll', + 'MostComments', + 'NewComments', + 'TopHour', + 'TopSixHour', + 'TopTwelveHour' +); -- alter all you enum columns -alter table local_user - alter column default_sort_type type sort_type_enum using default_sort_type::text::sort_type_enum; +ALTER TABLE local_user + ALTER COLUMN default_sort_type TYPE sort_type_enum + USING default_sort_type::text::sort_type_enum; -- drop the old enum -drop type sort_type_enum__; +DROP TYPE sort_type_enum__; + diff --git a/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/up.sql b/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/up.sql index 85bcfad7..7e5fcf77 100644 --- a/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/up.sql +++ b/migrations/2023-06-20-191145_add_listingtype_sorttype_3_6_9_months_enums/up.sql @@ -1,4 +1,10 @@ -- Update the enums -ALTER TYPE sort_type_enum ADD VALUE 'TopThreeMonths'; -ALTER TYPE sort_type_enum ADD VALUE 'TopSixMonths'; -ALTER TYPE sort_type_enum ADD VALUE 'TopNineMonths'; +ALTER TYPE sort_type_enum + ADD VALUE 'TopThreeMonths'; + +ALTER TYPE sort_type_enum + ADD VALUE 'TopSixMonths'; + +ALTER TYPE sort_type_enum + ADD VALUE 'TopNineMonths'; + diff --git a/migrations/2023-06-21-153242_add_captcha/down.sql b/migrations/2023-06-21-153242_add_captcha/down.sql index 4e5b8304..ab0fc231 100644 --- a/migrations/2023-06-21-153242_add_captcha/down.sql +++ b/migrations/2023-06-21-153242_add_captcha/down.sql @@ -1 +1,2 @@ -drop table captcha_answer; \ No newline at end of file +DROP TABLE captcha_answer; + diff --git a/migrations/2023-06-21-153242_add_captcha/up.sql b/migrations/2023-06-21-153242_add_captcha/up.sql index 5c566bc9..ede6f71f 100644 --- a/migrations/2023-06-21-153242_add_captcha/up.sql +++ b/migrations/2023-06-21-153242_add_captcha/up.sql @@ -1,6 +1,7 @@ -create table captcha_answer ( - id serial primary key, - uuid uuid not null unique default gen_random_uuid(), - answer text not null, - published timestamp not null default now() +CREATE TABLE captcha_answer ( + id serial PRIMARY KEY, + uuid uuid NOT NULL UNIQUE DEFAULT gen_random_uuid (), + answer text NOT NULL, + published timestamp NOT NULL DEFAULT now() ); + diff --git a/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/down.sql b/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/down.sql index ae8c4c78..e7836108 100644 --- a/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/down.sql +++ b/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/down.sql @@ -1,2 +1,4 @@ -- Add a no-op statement to prevent `diesel migration redo` errors -SELECT 1; +SELECT + 1; + diff --git a/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/up.sql b/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/up.sql index cbe3be9e..605f0ca9 100644 --- a/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/up.sql +++ b/migrations/2023-06-22-051755_fix_local_communities_marked_non_local/up.sql @@ -1,5 +1,11 @@ -update community c -set local=true -from local_site ls - join site s on ls.site_id=s.id -where c.instance_id=s.instance_id and not c.local; +UPDATE + community c +SET + local = TRUE +FROM + local_site ls + JOIN site s ON ls.site_id = s.id +WHERE + c.instance_id = s.instance_id + AND NOT c.local; + diff --git a/migrations/2023-06-22-101245_increase_user_theme_column_size/down.sql b/migrations/2023-06-22-101245_increase_user_theme_column_size/down.sql index 0731e068..64480d54 100644 --- a/migrations/2023-06-22-101245_increase_user_theme_column_size/down.sql +++ b/migrations/2023-06-22-101245_increase_user_theme_column_size/down.sql @@ -1,2 +1,6 @@ -alter table only local_user alter column theme TYPE character varying(20); -alter table only local_user alter column theme set default 'browser'::character varying; \ No newline at end of file +ALTER TABLE ONLY local_user + ALTER COLUMN theme TYPE character varying(20); + +ALTER TABLE ONLY local_user + ALTER COLUMN theme SET DEFAULT 'browser'::character varying; + diff --git a/migrations/2023-06-22-101245_increase_user_theme_column_size/up.sql b/migrations/2023-06-22-101245_increase_user_theme_column_size/up.sql index cbab2566..44f7dcf8 100644 --- a/migrations/2023-06-22-101245_increase_user_theme_column_size/up.sql +++ b/migrations/2023-06-22-101245_increase_user_theme_column_size/up.sql @@ -1,2 +1,6 @@ -alter table only local_user alter column theme type text; -alter table only local_user alter column theme set default 'browser'::text; +ALTER TABLE ONLY local_user + ALTER COLUMN theme TYPE text; + +ALTER TABLE ONLY local_user + ALTER COLUMN theme SET DEFAULT 'browser'::text; + diff --git a/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/down.sql b/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/down.sql index a4dfd50b..72ac5f2f 100644 --- a/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/down.sql +++ b/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/down.sql @@ -1 +1,3 @@ -alter table local_user drop column open_links_in_new_tab; +ALTER TABLE local_user + DROP COLUMN open_links_in_new_tab; + diff --git a/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/up.sql b/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/up.sql index 39a4b44a..9bc19855 100644 --- a/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/up.sql +++ b/migrations/2023-06-24-072904_add_open_links_in_new_tab_setting/up.sql @@ -1 +1,3 @@ -alter table local_user add column open_links_in_new_tab boolean default false not null; +ALTER TABLE local_user + ADD COLUMN open_links_in_new_tab boolean DEFAULT FALSE NOT NULL; + diff --git a/migrations/2023-06-24-185942_aggegates_published_indexes/down.sql b/migrations/2023-06-24-185942_aggegates_published_indexes/down.sql index fa7f7d48..840d54b0 100644 --- a/migrations/2023-06-24-185942_aggegates_published_indexes/down.sql +++ b/migrations/2023-06-24-185942_aggegates_published_indexes/down.sql @@ -1,2 +1,4 @@ -drop index idx_comment_aggregates_published; -drop index idx_community_aggregates_published; +DROP INDEX idx_comment_aggregates_published; + +DROP INDEX idx_community_aggregates_published; + diff --git a/migrations/2023-06-24-185942_aggegates_published_indexes/up.sql b/migrations/2023-06-24-185942_aggegates_published_indexes/up.sql index 42230af1..b7f9d30e 100644 --- a/migrations/2023-06-24-185942_aggegates_published_indexes/up.sql +++ b/migrations/2023-06-24-185942_aggegates_published_indexes/up.sql @@ -1,4 +1,5 @@ -- Add indexes on published column (needed for hot_rank updates) +CREATE INDEX idx_community_aggregates_published ON community_aggregates (published DESC); + +CREATE INDEX idx_comment_aggregates_published ON comment_aggregates (published DESC); -create index idx_community_aggregates_published on community_aggregates (published desc); -create index idx_comment_aggregates_published on comment_aggregates (published desc); \ No newline at end of file diff --git a/migrations/2023-06-27-065106_add_ui_settings/down.sql b/migrations/2023-06-27-065106_add_ui_settings/down.sql index 51fa7046..9f56764d 100644 --- a/migrations/2023-06-27-065106_add_ui_settings/down.sql +++ b/migrations/2023-06-27-065106_add_ui_settings/down.sql @@ -1,2 +1,6 @@ -alter table local_user drop column blur_nsfw; -alter table local_user drop column auto_expand; +ALTER TABLE local_user + DROP COLUMN blur_nsfw; + +ALTER TABLE local_user + DROP COLUMN auto_expand; + diff --git a/migrations/2023-06-27-065106_add_ui_settings/up.sql b/migrations/2023-06-27-065106_add_ui_settings/up.sql index 3c66c9c7..cff39601 100644 --- a/migrations/2023-06-27-065106_add_ui_settings/up.sql +++ b/migrations/2023-06-27-065106_add_ui_settings/up.sql @@ -1,6 +1,8 @@ - -- Add the blur_nsfw to the local user table as a setting -alter table local_user add column blur_nsfw boolean not null default true; +ALTER TABLE local_user + ADD COLUMN blur_nsfw boolean NOT NULL DEFAULT TRUE; -- Add the auto_expand to the local user table as a setting -alter table local_user add column auto_expand boolean not null default false; +ALTER TABLE local_user + ADD COLUMN auto_expand boolean NOT NULL DEFAULT FALSE; + diff --git a/migrations/2023-07-04-153335_add_optimized_indexes/down.sql b/migrations/2023-07-04-153335_add_optimized_indexes/down.sql index 9b4996e3..e69f0493 100644 --- a/migrations/2023-07-04-153335_add_optimized_indexes/down.sql +++ b/migrations/2023-07-04-153335_add_optimized_indexes/down.sql @@ -1,27 +1,46 @@ -- Drop the new indexes -drop index idx_person_admin; - -drop index idx_post_aggregates_featured_local_score; -drop index idx_post_aggregates_featured_local_newest_comment_time; -drop index idx_post_aggregates_featured_local_newest_comment_time_necro; -drop index idx_post_aggregates_featured_local_hot; -drop index idx_post_aggregates_featured_local_active; -drop index idx_post_aggregates_featured_local_published; -drop index idx_post_aggregates_published; - -drop index idx_post_aggregates_featured_community_score; -drop index idx_post_aggregates_featured_community_newest_comment_time; -drop index idx_post_aggregates_featured_community_newest_comment_time_necro; -drop index idx_post_aggregates_featured_community_hot; -drop index idx_post_aggregates_featured_community_active; -drop index idx_post_aggregates_featured_community_published; +DROP INDEX idx_person_admin; + +DROP INDEX idx_post_aggregates_featured_local_score; + +DROP INDEX idx_post_aggregates_featured_local_newest_comment_time; + +DROP INDEX idx_post_aggregates_featured_local_newest_comment_time_necro; + +DROP INDEX idx_post_aggregates_featured_local_hot; + +DROP INDEX idx_post_aggregates_featured_local_active; + +DROP INDEX idx_post_aggregates_featured_local_published; + +DROP INDEX idx_post_aggregates_published; + +DROP INDEX idx_post_aggregates_featured_community_score; + +DROP INDEX idx_post_aggregates_featured_community_newest_comment_time; + +DROP INDEX idx_post_aggregates_featured_community_newest_comment_time_necro; + +DROP INDEX idx_post_aggregates_featured_community_hot; + +DROP INDEX idx_post_aggregates_featured_community_active; + +DROP INDEX idx_post_aggregates_featured_community_published; -- Create single column indexes again -create index idx_post_aggregates_score on post_aggregates (score desc); -create index idx_post_aggregates_published on post_aggregates (published desc); -create index idx_post_aggregates_newest_comment_time on post_aggregates (newest_comment_time desc); -create index idx_post_aggregates_newest_comment_time_necro on post_aggregates (newest_comment_time_necro desc); -create index idx_post_aggregates_featured_community on post_aggregates (featured_community desc); -create index idx_post_aggregates_featured_local on post_aggregates (featured_local desc); -create index idx_post_aggregates_hot on post_aggregates (hot_rank desc); -create index idx_post_aggregates_active on post_aggregates (hot_rank_active desc); +CREATE INDEX idx_post_aggregates_score ON post_aggregates (score DESC); + +CREATE INDEX idx_post_aggregates_published ON post_aggregates (published DESC); + +CREATE INDEX idx_post_aggregates_newest_comment_time ON post_aggregates (newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_newest_comment_time_necro ON post_aggregates (newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_community ON post_aggregates (featured_community DESC); + +CREATE INDEX idx_post_aggregates_featured_local ON post_aggregates (featured_local DESC); + +CREATE INDEX idx_post_aggregates_hot ON post_aggregates (hot_rank DESC); + +CREATE INDEX idx_post_aggregates_active ON post_aggregates (hot_rank_active DESC); + diff --git a/migrations/2023-07-04-153335_add_optimized_indexes/up.sql b/migrations/2023-07-04-153335_add_optimized_indexes/up.sql index c55ecee9..85c5827f 100644 --- a/migrations/2023-07-04-153335_add_optimized_indexes/up.sql +++ b/migrations/2023-07-04-153335_add_optimized_indexes/up.sql @@ -1,32 +1,49 @@ -- Create an admin person index -create index if not exists idx_person_admin on person (admin); +CREATE INDEX IF NOT EXISTS idx_person_admin ON person (admin); -- Compound indexes, using featured_, then the other sorts, proved to be much faster -- Drop the old indexes -drop index idx_post_aggregates_score; -drop index idx_post_aggregates_published; -drop index idx_post_aggregates_newest_comment_time; -drop index idx_post_aggregates_newest_comment_time_necro; -drop index idx_post_aggregates_featured_community; -drop index idx_post_aggregates_featured_local; -drop index idx_post_aggregates_hot; -drop index idx_post_aggregates_active; +DROP INDEX idx_post_aggregates_score; + +DROP INDEX idx_post_aggregates_published; + +DROP INDEX idx_post_aggregates_newest_comment_time; + +DROP INDEX idx_post_aggregates_newest_comment_time_necro; + +DROP INDEX idx_post_aggregates_featured_community; + +DROP INDEX idx_post_aggregates_featured_local; + +DROP INDEX idx_post_aggregates_hot; + +DROP INDEX idx_post_aggregates_active; -- featured_local -create index idx_post_aggregates_featured_local_score on post_aggregates (featured_local desc, score desc); -create index idx_post_aggregates_featured_local_newest_comment_time on post_aggregates (featured_local desc, newest_comment_time desc); -create index idx_post_aggregates_featured_local_newest_comment_time_necro on post_aggregates (featured_local desc, newest_comment_time_necro desc); -create index idx_post_aggregates_featured_local_hot on post_aggregates (featured_local desc, hot_rank desc); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank_active desc); -create index idx_post_aggregates_featured_local_published on post_aggregates (featured_local desc, published desc); -create index idx_post_aggregates_published on post_aggregates (published desc); +CREATE INDEX idx_post_aggregates_featured_local_score ON post_aggregates (featured_local DESC, score DESC); + +CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time ON post_aggregates (featured_local DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_featured_local_newest_comment_time_necro ON post_aggregates (featured_local DESC, newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_local_hot ON post_aggregates (featured_local DESC, hot_rank DESC); + +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank_active DESC); + +CREATE INDEX idx_post_aggregates_featured_local_published ON post_aggregates (featured_local DESC, published DESC); + +CREATE INDEX idx_post_aggregates_published ON post_aggregates (published DESC); -- featured_community -create index idx_post_aggregates_featured_community_score on post_aggregates (featured_community desc, score desc); -create index idx_post_aggregates_featured_community_newest_comment_time on post_aggregates (featured_community desc, newest_comment_time desc); -create index idx_post_aggregates_featured_community_newest_comment_time_necro on post_aggregates (featured_community desc, newest_comment_time_necro desc); -create index idx_post_aggregates_featured_community_hot on post_aggregates (featured_community desc, hot_rank desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank_active desc); -create index idx_post_aggregates_featured_community_published on post_aggregates (featured_community desc, published desc); +CREATE INDEX idx_post_aggregates_featured_community_score ON post_aggregates (featured_community DESC, score DESC); + +CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time ON post_aggregates (featured_community DESC, newest_comment_time DESC); + +CREATE INDEX idx_post_aggregates_featured_community_newest_comment_time_necro ON post_aggregates (featured_community DESC, newest_comment_time_necro DESC); + +CREATE INDEX idx_post_aggregates_featured_community_hot ON post_aggregates (featured_community DESC, hot_rank DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank_active DESC); +CREATE INDEX idx_post_aggregates_featured_community_published ON post_aggregates (featured_community DESC, published DESC); diff --git a/migrations/2023-07-05-000058_person-admin/down.sql b/migrations/2023-07-05-000058_person-admin/down.sql index b77e1747..9eba8f58 100644 --- a/migrations/2023-07-05-000058_person-admin/down.sql +++ b/migrations/2023-07-05-000058_person-admin/down.sql @@ -1,2 +1,4 @@ -drop index idx_person_admin; -create index idx_person_admin on person(admin); \ No newline at end of file +DROP INDEX idx_person_admin; + +CREATE INDEX idx_person_admin ON person (admin); + diff --git a/migrations/2023-07-05-000058_person-admin/up.sql b/migrations/2023-07-05-000058_person-admin/up.sql index c71052ec..71884802 100644 --- a/migrations/2023-07-05-000058_person-admin/up.sql +++ b/migrations/2023-07-05-000058_person-admin/up.sql @@ -1,2 +1,7 @@ -drop index if exists idx_person_admin; -create index idx_person_admin on person(admin) where admin; -- allow quickly finding all admins (PersonView::admins) \ No newline at end of file +DROP INDEX IF EXISTS idx_person_admin; + +CREATE INDEX idx_person_admin ON person (admin) +WHERE + admin; + +-- allow quickly finding all admins (PersonView::admins) diff --git a/migrations/2023-07-06-151124_hot-rank-future/down.sql b/migrations/2023-07-06-151124_hot-rank-future/down.sql index b8f9a63f..4816c616 100644 --- a/migrations/2023-07-06-151124_hot-rank-future/down.sql +++ b/migrations/2023-07-06-151124_hot-rank-future/down.sql @@ -1,9 +1,9 @@ -CREATE OR REPLACE FUNCTION hot_rank(score numeric, published timestamp without time zone) +CREATE OR REPLACE FUNCTION hot_rank (score numeric, published timestamp without time zone) RETURNS integer AS $$ BEGIN -- hours_diff:=EXTRACT(EPOCH FROM (timezone('utc',now()) - published))/3600 - RETURN floor(10000 * log(greatest(1, score + 3)) / power(((EXTRACT(EPOCH FROM(timezone('utc', now()) - published)) / 3600) + 2), 1.8))::integer; + RETURN floor(10000 * log(greatest (1, score + 3)) / power(((EXTRACT(EPOCH FROM (timezone('utc', now()) - published)) / 3600) + 2), 1.8))::integer; END; $$ LANGUAGE plpgsql diff --git a/migrations/2023-07-06-151124_hot-rank-future/up.sql b/migrations/2023-07-06-151124_hot-rank-future/up.sql index 41baa673..83b5f0f0 100644 --- a/migrations/2023-07-06-151124_hot-rank-future/up.sql +++ b/migrations/2023-07-06-151124_hot-rank-future/up.sql @@ -1,11 +1,11 @@ -CREATE OR REPLACE FUNCTION hot_rank(score numeric, published timestamp without time zone) +CREATE OR REPLACE FUNCTION hot_rank (score numeric, published timestamp without time zone) RETURNS integer AS $$ DECLARE hours_diff numeric := EXTRACT(EPOCH FROM (timezone('utc', now()) - published)) / 3600; BEGIN IF (hours_diff > 0) THEN - RETURN floor(10000 * log(greatest(1, score + 3)) / power((hours_diff + 2), 1.8))::integer; + RETURN floor(10000 * log(greatest (1, score + 3)) / power((hours_diff + 2), 1.8))::integer; ELSE RETURN 0; END IF; diff --git a/migrations/2023-07-08-101154_fix_soft_delete_aggregates/down.sql b/migrations/2023-07-08-101154_fix_soft_delete_aggregates/down.sql index b9616dee..d9fce66e 100644 --- a/migrations/2023-07-08-101154_fix_soft_delete_aggregates/down.sql +++ b/migrations/2023-07-08-101154_fix_soft_delete_aggregates/down.sql @@ -1,105 +1,129 @@ -- 2023-06-19-120700_no_double_deletion/up.sql -create or replace function was_removed_or_deleted(TG_OP text, OLD record, NEW record) -RETURNS boolean -LANGUAGE plpgsql -as $$ - begin - IF (TG_OP = 'INSERT') THEN - return false; - end if; - - IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 'f' AND NEW.deleted = 't') OR - (OLD.removed = 'f' AND NEW.removed = 't') - ); -END $$; +CREATE OR REPLACE FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + RETURN FALSE; + END IF; + IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 'f' + AND NEW.deleted = 't') + OR (OLD.removed = 'f' + AND NEW.removed = 't')); +END +$$; -- 2022-04-04-183652_update_community_aggregates_on_soft_delete/up.sql -create or replace function was_restored_or_created(TG_OP text, OLD record, NEW record) +CREATE OR REPLACE FUNCTION was_restored_or_created (TG_OP text, OLD record, NEW record) RETURNS boolean LANGUAGE plpgsql -as $$ -begin + AS $$ +BEGIN IF (TG_OP = 'DELETE') THEN - return false; - end if; - + RETURN FALSE; + END IF; IF (TG_OP = 'INSERT') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND ( - (OLD.deleted = 't' AND NEW.deleted = 'f') OR - (OLD.removed = 't' AND NEW.removed = 'f') - ); -END $$; + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND ((OLD.deleted = 't' + AND NEW.deleted = 'f') + OR (OLD.removed = 't' + AND NEW.removed = 'f')); +END +$$; -- 2021-08-02-002342_comment_count_fixes/up.sql -create or replace function post_aggregates_comment_deleted() -returns trigger language plpgsql -as $$ -begin - IF NEW.deleted = TRUE THEN - update post_aggregates pa - set comments = comments - 1 - where pa.post_id = NEW.post_id; - ELSE - update post_aggregates pa - set comments = comments + 1 - where pa.post_id = NEW.post_id; - END IF; - return null; -end $$; - -create trigger post_aggregates_comment_set_deleted -after update of deleted on comment -for each row -execute procedure post_aggregates_comment_deleted(); - -create or replace function post_aggregates_comment_count() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set comments = comments + 1, - newest_comment_time = NEW.published - where pa.post_id = NEW.post_id; +CREATE OR REPLACE FUNCTION post_aggregates_comment_deleted () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF NEW.deleted = TRUE THEN + UPDATE + post_aggregates pa + SET + comments = comments - 1 + WHERE + pa.post_id = NEW.post_id; + ELSE + UPDATE + post_aggregates pa + SET + comments = comments + 1 + WHERE + pa.post_id = NEW.post_id; + END IF; + RETURN NULL; +END +$$; - -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time_necro = NEW.published - from post p - where pa.post_id = p.id - and pa.post_id = NEW.post_id - -- Fix issue with being able to necro-bump your own post - and NEW.creator_id != p.creator_id - and pa.published > ('now'::timestamp - '2 days'::interval); +CREATE TRIGGER post_aggregates_comment_set_deleted + AFTER UPDATE OF deleted ON comment + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_comment_deleted (); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - ELSIF (TG_OP = 'UPDATE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set comments = comments - 1 - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1, + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id; + -- A 2 day necro-bump limit + UPDATE + post_aggregates pa + SET + newest_comment_time_necro = NEW.published + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = NEW.post_id + -- Fix issue with being able to necro-bump your own post + AND NEW.creator_id != p.creator_id + AND pa.published > ('now'::timestamp - '2 days'::interval); + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + ELSIF (TG_OP = 'UPDATE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + comments = comments - 1 + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; -- 2020-12-10-152350_create_post_aggregates/up.sql -create or replace trigger post_aggregates_comment_count -after insert or delete on comment -for each row -execute procedure post_aggregates_comment_count(); +CREATE OR REPLACE TRIGGER post_aggregates_comment_count + AFTER INSERT OR DELETE ON comment + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_comment_count (); + diff --git a/migrations/2023-07-08-101154_fix_soft_delete_aggregates/up.sql b/migrations/2023-07-08-101154_fix_soft_delete_aggregates/up.sql index abc89d28..2884f934 100644 --- a/migrations/2023-07-08-101154_fix_soft_delete_aggregates/up.sql +++ b/migrations/2023-07-08-101154_fix_soft_delete_aggregates/up.sql @@ -1,81 +1,104 @@ -- Fix for duplicated decrementations when both `deleted` and `removed` fields are set subsequently -create or replace function was_removed_or_deleted(TG_OP text, OLD record, NEW record) -RETURNS boolean -LANGUAGE plpgsql -as $$ - begin - IF (TG_OP = 'INSERT') THEN - return false; - end if; - - IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND OLD.deleted = 'f' AND OLD.removed = 'f' AND ( - NEW.deleted = 't' OR NEW.removed = 't' - ); -END $$; +CREATE OR REPLACE FUNCTION was_removed_or_deleted (TG_OP text, OLD record, NEW record) + RETURNS boolean + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + RETURN FALSE; + END IF; + IF (TG_OP = 'DELETE' AND OLD.deleted = 'f' AND OLD.removed = 'f') THEN + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND OLD.deleted = 'f' + AND OLD.removed = 'f' + AND (NEW.deleted = 't' + OR NEW.removed = 't'); +END +$$; -create or replace function was_restored_or_created(TG_OP text, OLD record, NEW record) +CREATE OR REPLACE FUNCTION was_restored_or_created (TG_OP text, OLD record, NEW record) RETURNS boolean LANGUAGE plpgsql -as $$ -begin + AS $$ +BEGIN IF (TG_OP = 'DELETE') THEN - return false; - end if; - + RETURN FALSE; + END IF; IF (TG_OP = 'INSERT') THEN - return true; - end if; - - return TG_OP = 'UPDATE' AND NEW.deleted = 'f' AND NEW.removed = 'f' AND ( - OLD.deleted = 't' OR OLD.removed = 't' - ); -END $$; + RETURN TRUE; + END IF; + RETURN TG_OP = 'UPDATE' + AND NEW.deleted = 'f' + AND NEW.removed = 'f' + AND (OLD.deleted = 't' + OR OLD.removed = 't'); +END +$$; -- Fix for post's comment count not updating after setting `removed` to 't' -drop trigger if exists post_aggregates_comment_set_deleted on comment; -drop function post_aggregates_comment_deleted(); +DROP TRIGGER IF EXISTS post_aggregates_comment_set_deleted ON comment; + +DROP FUNCTION post_aggregates_comment_deleted (); -create or replace function post_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin +CREATE OR REPLACE FUNCTION post_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN -- Check for post existence - it may not exist anymore IF TG_OP = 'INSERT' OR EXISTS ( - select 1 from post p where p.id = OLD.post_id - ) THEN - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update post_aggregates pa - set comments = comments + 1 where pa.post_id = NEW.post_id; - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update post_aggregates pa - set comments = comments - 1 where pa.post_id = OLD.post_id; + SELECT + 1 + FROM + post p + WHERE + p.id = OLD.post_id) THEN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + post_aggregates pa + SET + comments = comments + 1 + WHERE + pa.post_id = NEW.post_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + post_aggregates pa + SET + comments = comments - 1 + WHERE + pa.post_id = OLD.post_id; END IF; END IF; - IF TG_OP = 'INSERT' THEN - update post_aggregates pa - set newest_comment_time = NEW.published - where pa.post_id = NEW.post_id; - + UPDATE + post_aggregates pa + SET + newest_comment_time = NEW.published + WHERE + pa.post_id = NEW.post_id; -- A 2 day necro-bump limit - update post_aggregates pa - set newest_comment_time_necro = NEW.published - from post p - where pa.post_id = p.id - and pa.post_id = NEW.post_id - -- Fix issue with being able to necro-bump your own post - and NEW.creator_id != p.creator_id - and pa.published > ('now'::timestamp - '2 days'::interval); + UPDATE + post_aggregates pa + SET + newest_comment_time_necro = NEW.published + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = NEW.post_id + -- Fix issue with being able to necro-bump your own post + AND NEW.creator_id != p.creator_id + AND pa.published > ('now'::timestamp - '2 days'::interval); END IF; + RETURN NULL; +END +$$; - return null; -end $$; +CREATE OR REPLACE TRIGGER post_aggregates_comment_count + AFTER INSERT OR DELETE OR UPDATE OF removed, + deleted ON comment + FOR EACH ROW + EXECUTE PROCEDURE post_aggregates_comment_count (); -create or replace trigger post_aggregates_comment_count - after insert or delete or update of removed, deleted on comment - for each row -execute procedure post_aggregates_comment_count(); \ No newline at end of file diff --git a/migrations/2023-07-10-075550_add-infinite-scroll-setting/down.sql b/migrations/2023-07-10-075550_add-infinite-scroll-setting/down.sql index 66ff507d..721922db 100644 --- a/migrations/2023-07-10-075550_add-infinite-scroll-setting/down.sql +++ b/migrations/2023-07-10-075550_add-infinite-scroll-setting/down.sql @@ -1 +1,3 @@ -alter table local_user drop column infinite_scroll_enabled; +ALTER TABLE local_user + DROP COLUMN infinite_scroll_enabled; + diff --git a/migrations/2023-07-10-075550_add-infinite-scroll-setting/up.sql b/migrations/2023-07-10-075550_add-infinite-scroll-setting/up.sql index 905bc710..b435e2e2 100644 --- a/migrations/2023-07-10-075550_add-infinite-scroll-setting/up.sql +++ b/migrations/2023-07-10-075550_add-infinite-scroll-setting/up.sql @@ -1 +1,3 @@ -alter table local_user add column infinite_scroll_enabled boolean default false not null; +ALTER TABLE local_user + ADD COLUMN infinite_scroll_enabled boolean DEFAULT FALSE NOT NULL; + diff --git a/migrations/2023-07-11-084714_receive_activity_table/down.sql b/migrations/2023-07-11-084714_receive_activity_table/down.sql index ea4f4d4a..188b4afa 100644 --- a/migrations/2023-07-11-084714_receive_activity_table/down.sql +++ b/migrations/2023-07-11-084714_receive_activity_table/down.sql @@ -1,21 +1,28 @@ -create table activity ( - id serial primary key, - data jsonb not null, - local boolean not null default true, - published timestamp not null default now(), +CREATE TABLE activity ( + id serial PRIMARY KEY, + data jsonb NOT NULL, + local boolean NOT NULL DEFAULT TRUE, + published timestamp NOT NULL DEFAULT now(), updated timestamp, - ap_id text not null, - sensitive boolean not null default true + ap_id text NOT NULL, + sensitive boolean NOT NULL DEFAULT TRUE ); -insert into activity(ap_id, data, sensitive, published) - select ap_id, data, sensitive, published - from sent_activity - order by id desc - limit 100000; +INSERT INTO activity (ap_id, data, sensitive, published) +SELECT + ap_id, + data, + sensitive, + published +FROM + sent_activity +ORDER BY + id DESC +LIMIT 100000; -- We cant copy received_activity entries back into activities table because we dont have data -- which is mandatory. +DROP TABLE sent_activity; + +DROP TABLE received_activity; -drop table sent_activity; -drop table received_activity; \ No newline at end of file diff --git a/migrations/2023-07-11-084714_receive_activity_table/up.sql b/migrations/2023-07-11-084714_receive_activity_table/up.sql index c6b30b7b..4d723491 100644 --- a/migrations/2023-07-11-084714_receive_activity_table/up.sql +++ b/migrations/2023-07-11-084714_receive_activity_table/up.sql @@ -1,35 +1,48 @@ -- outgoing activities, need to be stored to be later server over http -- we change data column from jsonb to json for decreased size -- https://stackoverflow.com/a/22910602 -create table sent_activity ( - id bigserial primary key, - ap_id text unique not null, - data json not null, - sensitive boolean not null, - published timestamp not null default now() +CREATE TABLE sent_activity ( + id bigserial PRIMARY KEY, + ap_id text UNIQUE NOT NULL, + data json NOT NULL, + sensitive boolean NOT NULL, + published timestamp NOT NULL DEFAULT now() ); -- incoming activities, we only need the id to avoid processing the same activity multiple times -create table received_activity ( - id bigserial primary key, - ap_id text unique not null, - published timestamp not null default now() +CREATE TABLE received_activity ( + id bigserial PRIMARY KEY, + ap_id text UNIQUE NOT NULL, + published timestamp NOT NULL DEFAULT now() ); -- copy sent activities to new table. only copy last 100k for faster migration -insert into sent_activity(ap_id, data, sensitive, published) - select ap_id, data, sensitive, published - from activity - where local = true - order by id desc - limit 100000; +INSERT INTO sent_activity (ap_id, data, sensitive, published) +SELECT + ap_id, + data, + sensitive, + published +FROM + activity +WHERE + local = TRUE +ORDER BY + id DESC +LIMIT 100000; -- copy received activities to new table. only last 1m for faster migration -insert into received_activity(ap_id, published) - select ap_id, published - from activity - where local = false - order by id desc - limit 1000000; +INSERT INTO received_activity (ap_id, published) +SELECT + ap_id, + published +FROM + activity +WHERE + local = FALSE +ORDER BY + id DESC +LIMIT 1000000; + +DROP TABLE activity; -drop table activity; diff --git a/migrations/2023-07-14-154840_add_optimized_indexes_published/down.sql b/migrations/2023-07-14-154840_add_optimized_indexes_published/down.sql index 5661a314..7bc306f9 100644 --- a/migrations/2023-07-14-154840_add_optimized_indexes_published/down.sql +++ b/migrations/2023-07-14-154840_add_optimized_indexes_published/down.sql @@ -1,26 +1,40 @@ -- Drop the new indexes -drop index idx_post_aggregates_featured_local_most_comments; -drop index idx_post_aggregates_featured_local_hot; -drop index idx_post_aggregates_featured_local_active; -drop index idx_post_aggregates_featured_local_score; -drop index idx_post_aggregates_featured_community_hot; -drop index idx_post_aggregates_featured_community_active; -drop index idx_post_aggregates_featured_community_score; -drop index idx_post_aggregates_featured_community_most_comments; -drop index idx_comment_aggregates_hot; -drop index idx_comment_aggregates_score; +DROP INDEX idx_post_aggregates_featured_local_most_comments; + +DROP INDEX idx_post_aggregates_featured_local_hot; + +DROP INDEX idx_post_aggregates_featured_local_active; + +DROP INDEX idx_post_aggregates_featured_local_score; + +DROP INDEX idx_post_aggregates_featured_community_hot; + +DROP INDEX idx_post_aggregates_featured_community_active; + +DROP INDEX idx_post_aggregates_featured_community_score; + +DROP INDEX idx_post_aggregates_featured_community_most_comments; + +DROP INDEX idx_comment_aggregates_hot; + +DROP INDEX idx_comment_aggregates_score; -- Add the old ones back in -- featured_local -create index idx_post_aggregates_featured_local_hot on post_aggregates (featured_local desc, hot_rank desc); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank_active desc); -create index idx_post_aggregates_featured_local_score on post_aggregates (featured_local desc, score desc); +CREATE INDEX idx_post_aggregates_featured_local_hot ON post_aggregates (featured_local DESC, hot_rank DESC); + +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank_active DESC); + +CREATE INDEX idx_post_aggregates_featured_local_score ON post_aggregates (featured_local DESC, score DESC); -- featured_community -create index idx_post_aggregates_featured_community_hot on post_aggregates (featured_community desc, hot_rank desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank_active desc); -create index idx_post_aggregates_featured_community_score on post_aggregates (featured_community desc, score desc); +CREATE INDEX idx_post_aggregates_featured_community_hot ON post_aggregates (featured_community DESC, hot_rank DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank_active DESC); + +CREATE INDEX idx_post_aggregates_featured_community_score ON post_aggregates (featured_community DESC, score DESC); + +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank DESC); -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank desc); -create index idx_comment_aggregates_score on comment_aggregates (score desc); +CREATE INDEX idx_comment_aggregates_score ON comment_aggregates (score DESC); diff --git a/migrations/2023-07-14-154840_add_optimized_indexes_published/up.sql b/migrations/2023-07-14-154840_add_optimized_indexes_published/up.sql index 94e426fc..728ca38d 100644 --- a/migrations/2023-07-14-154840_add_optimized_indexes_published/up.sql +++ b/migrations/2023-07-14-154840_add_optimized_indexes_published/up.sql @@ -1,30 +1,42 @@ -- Drop the old indexes -drop index idx_post_aggregates_featured_local_hot; -drop index idx_post_aggregates_featured_local_active; -drop index idx_post_aggregates_featured_local_score; -drop index idx_post_aggregates_featured_community_hot; -drop index idx_post_aggregates_featured_community_active; -drop index idx_post_aggregates_featured_community_score; -drop index idx_comment_aggregates_hot; -drop index idx_comment_aggregates_score; +DROP INDEX idx_post_aggregates_featured_local_hot; --- Add a published desc, to the end of the hot and active ranks +DROP INDEX idx_post_aggregates_featured_local_active; + +DROP INDEX idx_post_aggregates_featured_local_score; + +DROP INDEX idx_post_aggregates_featured_community_hot; + +DROP INDEX idx_post_aggregates_featured_community_active; + +DROP INDEX idx_post_aggregates_featured_community_score; + +DROP INDEX idx_comment_aggregates_hot; + +DROP INDEX idx_comment_aggregates_score; +-- Add a published desc, to the end of the hot and active ranks -- Add missing most comments index -create index idx_post_aggregates_featured_local_most_comments on post_aggregates (featured_local desc, comments desc, published desc); -create index idx_post_aggregates_featured_community_most_comments on post_aggregates (featured_community desc, comments desc, published desc); +CREATE INDEX idx_post_aggregates_featured_local_most_comments ON post_aggregates (featured_local DESC, comments DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_community_most_comments ON post_aggregates (featured_community DESC, comments DESC, published DESC); -- featured_local -create index idx_post_aggregates_featured_local_hot on post_aggregates (featured_local desc, hot_rank desc, published desc); -create index idx_post_aggregates_featured_local_active on post_aggregates (featured_local desc, hot_rank_active desc, published desc); -create index idx_post_aggregates_featured_local_score on post_aggregates (featured_local desc, score desc, published desc); +CREATE INDEX idx_post_aggregates_featured_local_hot ON post_aggregates (featured_local DESC, hot_rank DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_local_active ON post_aggregates (featured_local DESC, hot_rank_active DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_local_score ON post_aggregates (featured_local DESC, score DESC, published DESC); -- featured_community -create index idx_post_aggregates_featured_community_hot on post_aggregates (featured_community desc, hot_rank desc, published desc); -create index idx_post_aggregates_featured_community_active on post_aggregates (featured_community desc, hot_rank_active desc, published desc); -create index idx_post_aggregates_featured_community_score on post_aggregates (featured_community desc, score desc, published desc); +CREATE INDEX idx_post_aggregates_featured_community_hot ON post_aggregates (featured_community DESC, hot_rank DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_community_active ON post_aggregates (featured_community DESC, hot_rank_active DESC, published DESC); + +CREATE INDEX idx_post_aggregates_featured_community_score ON post_aggregates (featured_community DESC, score DESC, published DESC); -- Fixing some comment aggregates ones -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank desc, published desc); -create index idx_comment_aggregates_score on comment_aggregates (score desc, published desc); +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank DESC, published DESC); + +CREATE INDEX idx_comment_aggregates_score ON comment_aggregates (score DESC, published DESC); diff --git a/migrations/2023-07-14-215339_aggregates_nonzero_indexes/down.sql b/migrations/2023-07-14-215339_aggregates_nonzero_indexes/down.sql index 3e247b58..658853eb 100644 --- a/migrations/2023-07-14-215339_aggregates_nonzero_indexes/down.sql +++ b/migrations/2023-07-14-215339_aggregates_nonzero_indexes/down.sql @@ -1,4 +1,7 @@ -- This file should undo anything in `up.sql` DROP INDEX idx_community_aggregates_nonzero_hotrank; + DROP INDEX idx_comment_aggregates_nonzero_hotrank; -DROP INDEX idx_post_aggregates_nonzero_hotrank; \ No newline at end of file + +DROP INDEX idx_post_aggregates_nonzero_hotrank; + diff --git a/migrations/2023-07-14-215339_aggregates_nonzero_indexes/up.sql b/migrations/2023-07-14-215339_aggregates_nonzero_indexes/up.sql index 2d3cd3b2..d51aa0dc 100644 --- a/migrations/2023-07-14-215339_aggregates_nonzero_indexes/up.sql +++ b/migrations/2023-07-14-215339_aggregates_nonzero_indexes/up.sql @@ -1,4 +1,13 @@ -- Your SQL goes here -CREATE INDEX idx_community_aggregates_nonzero_hotrank ON community_aggregates (published) WHERE hot_rank != 0; -CREATE INDEX idx_comment_aggregates_nonzero_hotrank ON comment_aggregates (published) WHERE hot_rank != 0; -CREATE INDEX idx_post_aggregates_nonzero_hotrank ON post_aggregates (published DESC) WHERE hot_rank != 0 OR hot_rank_active != 0; \ No newline at end of file +CREATE INDEX idx_community_aggregates_nonzero_hotrank ON community_aggregates (published) +WHERE + hot_rank != 0; + +CREATE INDEX idx_comment_aggregates_nonzero_hotrank ON comment_aggregates (published) +WHERE + hot_rank != 0; + +CREATE INDEX idx_post_aggregates_nonzero_hotrank ON post_aggregates (published DESC) +WHERE + hot_rank != 0 OR hot_rank_active != 0; + diff --git a/migrations/2023-07-18-082614_post_aggregates_community_id/down.sql b/migrations/2023-07-18-082614_post_aggregates_community_id/down.sql index 91e2dc86..8e221465 100644 --- a/migrations/2023-07-18-082614_post_aggregates_community_id/down.sql +++ b/migrations/2023-07-18-082614_post_aggregates_community_id/down.sql @@ -1,20 +1,21 @@ -- This file should undo anything in `up.sql` - -CREATE OR REPLACE FUNCTION post_aggregates_post() - RETURNS trigger +CREATE OR REPLACE FUNCTION post_aggregates_post () + RETURNS TRIGGER LANGUAGE plpgsql -AS -$$ + AS $$ BEGIN IF (TG_OP = 'INSERT') THEN INSERT INTO post_aggregates (post_id, published, newest_comment_time, newest_comment_time_necro) - VALUES (NEW.id, NEW.published, NEW.published, NEW.published); + VALUES (NEW.id, NEW.published, NEW.published, NEW.published); ELSIF (TG_OP = 'DELETE') THEN - DELETE FROM post_aggregates WHERE post_id = OLD.id; + DELETE FROM post_aggregates + WHERE post_id = OLD.id; END IF; RETURN NULL; END $$; -ALTER TABLE post_aggregates DROP COLUMN community_id, DROP COLUMN creator_id; +ALTER TABLE post_aggregates + DROP COLUMN community_id, + DROP COLUMN creator_id; diff --git a/migrations/2023-07-18-082614_post_aggregates_community_id/up.sql b/migrations/2023-07-18-082614_post_aggregates_community_id/up.sql index f28701da..d909ce02 100644 --- a/migrations/2023-07-18-082614_post_aggregates_community_id/up.sql +++ b/migrations/2023-07-18-082614_post_aggregates_community_id/up.sql @@ -3,33 +3,33 @@ ALTER TABLE post_aggregates ADD COLUMN community_id integer REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE, ADD COLUMN creator_id integer REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE; -CREATE OR REPLACE FUNCTION post_aggregates_post() - RETURNS trigger +CREATE OR REPLACE FUNCTION post_aggregates_post () + RETURNS TRIGGER LANGUAGE plpgsql -AS -$$ + AS $$ BEGIN IF (TG_OP = 'INSERT') THEN - INSERT INTO post_aggregates (post_id, - published, - newest_comment_time, - newest_comment_time_necro, - community_id, - creator_id) - VALUES (NEW.id, NEW.published, NEW.published, NEW.published, NEW.community_id, NEW.creator_id); + INSERT INTO post_aggregates (post_id, published, newest_comment_time, newest_comment_time_necro, community_id, creator_id) + VALUES (NEW.id, NEW.published, NEW.published, NEW.published, NEW.community_id, NEW.creator_id); ELSIF (TG_OP = 'DELETE') THEN - DELETE FROM post_aggregates WHERE post_id = OLD.id; + DELETE FROM post_aggregates + WHERE post_id = OLD.id; END IF; RETURN NULL; END $$; -UPDATE post_aggregates -SET community_id=post.community_id, - creator_id=post.creator_id -FROM post -WHERE post.id = post_aggregates.post_id; +UPDATE + post_aggregates +SET + community_id = post.community_id, + creator_id = post.creator_id +FROM + post +WHERE + post.id = post_aggregates.post_id; ALTER TABLE post_aggregates ALTER COLUMN community_id SET NOT NULL, - ALTER COLUMN creator_id SET NOT NULL; \ No newline at end of file + ALTER COLUMN creator_id SET NOT NULL; + diff --git a/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/down.sql b/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/down.sql index 9f784c06..f7cdf93e 100644 --- a/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/down.sql +++ b/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/down.sql @@ -1,4 +1,6 @@ -drop index idx_comment_aggregates_hot, idx_comment_aggregates_score; +DROP INDEX idx_comment_aggregates_hot, idx_comment_aggregates_score; + +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank DESC, published DESC); + +CREATE INDEX idx_comment_aggregates_score ON comment_aggregates (score DESC, published DESC); -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank desc, published desc); -create index idx_comment_aggregates_score on comment_aggregates (score desc, published desc); diff --git a/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/up.sql b/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/up.sql index 02eff3ed..94ad1cc6 100644 --- a/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/up.sql +++ b/migrations/2023-07-19-163511_comment_sort_hot_rank_then_score/up.sql @@ -1,10 +1,10 @@ -- Alter the comment_aggregates hot sort to sort by score after hot_rank. --- Reason being, is that hot_ranks go to zero after a few days, +-- Reason being, is that hot_ranks go to zero after a few days, -- and then comments should be sorted by score, not published. +DROP INDEX idx_comment_aggregates_hot, idx_comment_aggregates_score; -drop index idx_comment_aggregates_hot, idx_comment_aggregates_score; - -create index idx_comment_aggregates_hot on comment_aggregates (hot_rank desc, score desc); +CREATE INDEX idx_comment_aggregates_hot ON comment_aggregates (hot_rank DESC, score DESC); -- Remove published from this sort, its pointless -create index idx_comment_aggregates_score on comment_aggregates (score desc); +CREATE INDEX idx_comment_aggregates_score ON comment_aggregates (score DESC); + diff --git a/migrations/2023-07-24-232635_trigram-index/up.sql b/migrations/2023-07-24-232635_trigram-index/up.sql index ed648b6e..4875d280 100644 --- a/migrations/2023-07-24-232635_trigram-index/up.sql +++ b/migrations/2023-07-24-232635_trigram-index/up.sql @@ -1,10 +1,10 @@ CREATE EXTENSION IF NOT EXISTS pg_trgm; -CREATE INDEX IF NOT EXISTS idx_comment_content_trigram ON comment USING gin(content gin_trgm_ops); +CREATE INDEX IF NOT EXISTS idx_comment_content_trigram ON comment USING gin (content gin_trgm_ops); -CREATE INDEX IF NOT EXISTS idx_post_trigram ON post USING gin(name gin_trgm_ops, body gin_trgm_ops); +CREATE INDEX IF NOT EXISTS idx_post_trigram ON post USING gin (name gin_trgm_ops, body gin_trgm_ops); -CREATE INDEX IF NOT EXISTS idx_person_trigram ON person USING gin(name gin_trgm_ops, display_name gin_trgm_ops); +CREATE INDEX IF NOT EXISTS idx_person_trigram ON person USING gin (name gin_trgm_ops, display_name gin_trgm_ops); -CREATE INDEX IF NOT EXISTS idx_community_trigram ON community USING gin(name gin_trgm_ops, title gin_trgm_ops); +CREATE INDEX IF NOT EXISTS idx_community_trigram ON community USING gin (name gin_trgm_ops, title gin_trgm_ops); diff --git a/migrations/2023-07-26-000217_create_controversial_indexes/down.sql b/migrations/2023-07-26-000217_create_controversial_indexes/down.sql index a355546d..f4c5b4a1 100644 --- a/migrations/2023-07-26-000217_create_controversial_indexes/down.sql +++ b/migrations/2023-07-26-000217_create_controversial_indexes/down.sql @@ -1,63 +1,115 @@ -- Update comment_aggregates_score trigger function to exclude controversy_rank update -create or replace function comment_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update comment_aggregates ca - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end - where ca.comment_id = NEW.comment_id; - - ELSIF (TG_OP = 'DELETE') THEN - -- Join to comment because that comment may not exist anymore - update comment_aggregates ca - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end - from comment c - where ca.comment_id = c.id - and ca.comment_id = OLD.comment_id; - - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION comment_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + comment_aggregates ca + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + ca.comment_id = NEW.comment_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to comment because that comment may not exist anymore + UPDATE + comment_aggregates ca + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END + FROM + comment c + WHERE + ca.comment_id = c.id + AND ca.comment_id = OLD.comment_id; + END IF; + RETURN NULL; +END +$$; -- Update post_aggregates_score trigger function to exclude controversy_rank update -create or replace function post_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end - where pa.post_id = NEW.post_id; - - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION post_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END + WHERE + pa.post_id = NEW.post_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; -- Drop the indexes -drop index if exists idx_post_aggregates_featured_local_controversy; -drop index if exists idx_post_aggregates_featured_community_controversy; -drop index if exists idx_comment_aggregates_controversy; +DROP INDEX IF EXISTS idx_post_aggregates_featured_local_controversy; + +DROP INDEX IF EXISTS idx_post_aggregates_featured_community_controversy; + +DROP INDEX IF EXISTS idx_comment_aggregates_controversy; -- Remove the added columns from the tables -alter table post_aggregates drop column controversy_rank; -alter table comment_aggregates drop column controversy_rank; +ALTER TABLE post_aggregates + DROP COLUMN controversy_rank; + +ALTER TABLE comment_aggregates + DROP COLUMN controversy_rank; -- Remove function -drop function controversy_rank(numeric, numeric); +DROP FUNCTION controversy_rank (numeric, numeric); diff --git a/migrations/2023-07-26-000217_create_controversial_indexes/up.sql b/migrations/2023-07-26-000217_create_controversial_indexes/up.sql index f50a706b..eb1d712e 100644 --- a/migrations/2023-07-26-000217_create_controversial_indexes/up.sql +++ b/migrations/2023-07-26-000217_create_controversial_indexes/up.sql @@ -1,97 +1,184 @@ -- Need to add immutable to the controversy_rank function in order to index by it - -- Controversy Rank: -- if downvotes <= 0 or upvotes <= 0: --- 0 +-- 0 -- else: --- (upvotes + downvotes) * min(upvotes, downvotes) / max(upvotes, downvotes) -create or replace function controversy_rank(upvotes numeric, downvotes numeric) -returns float as $$ -begin - if downvotes <= 0 or upvotes <= 0 then - return 0; - else - return (upvotes + downvotes) * - case when upvotes > downvotes - then downvotes::float / upvotes::float - else upvotes::float / downvotes::float - end; - end if; -end; $$ +-- (upvotes + downvotes) * min(upvotes, downvotes) / max(upvotes, downvotes) +CREATE OR REPLACE FUNCTION controversy_rank (upvotes numeric, downvotes numeric) + RETURNS float + AS $$ +BEGIN + IF downvotes <= 0 OR upvotes <= 0 THEN + RETURN 0; + ELSE + RETURN (upvotes + downvotes) * CASE WHEN upvotes > downvotes THEN + downvotes::float / upvotes::float + ELSE + upvotes::float / downvotes::float + END; + END IF; +END; +$$ LANGUAGE plpgsql IMMUTABLE; -- Aggregates -alter table post_aggregates add column controversy_rank float not null default 0; -alter table comment_aggregates add column controversy_rank float not null default 0; +ALTER TABLE post_aggregates + ADD COLUMN controversy_rank float NOT NULL DEFAULT 0; + +ALTER TABLE comment_aggregates + ADD COLUMN controversy_rank float NOT NULL DEFAULT 0; -- Populate them initially -- Note: After initial population, these are updated with vote triggers -update post_aggregates set controversy_rank = controversy_rank(upvotes::numeric, downvotes::numeric); -update comment_aggregates set controversy_rank = controversy_rank(upvotes::numeric, downvotes::numeric); +UPDATE + post_aggregates +SET + controversy_rank = controversy_rank (upvotes::numeric, downvotes::numeric); + +UPDATE + comment_aggregates +SET + controversy_rank = controversy_rank (upvotes::numeric, downvotes::numeric); -- Create single column indexes -create index idx_post_aggregates_featured_local_controversy on post_aggregates (featured_local desc, controversy_rank desc); -create index idx_post_aggregates_featured_community_controversy on post_aggregates (featured_community desc, controversy_rank desc); -create index idx_comment_aggregates_controversy on comment_aggregates (controversy_rank desc); +CREATE INDEX idx_post_aggregates_featured_local_controversy ON post_aggregates (featured_local DESC, controversy_rank DESC); --- Update post_aggregates_score trigger function to include controversy_rank update -create or replace function post_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update post_aggregates pa - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end, - controversy_rank = controversy_rank(pa.upvotes + case when NEW.score = 1 then 1 else 0 end::numeric, - pa.downvotes + case when NEW.score = -1 then 1 else 0 end::numeric) - where pa.post_id = NEW.post_id; +CREATE INDEX idx_post_aggregates_featured_community_controversy ON post_aggregates (featured_community DESC, controversy_rank DESC); - ELSIF (TG_OP = 'DELETE') THEN - -- Join to post because that post may not exist anymore - update post_aggregates pa - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end, - controversy_rank = controversy_rank(pa.upvotes + case when NEW.score = 1 then 1 else 0 end::numeric, - pa.downvotes + case when NEW.score = -1 then 1 else 0 end::numeric) - from post p - where pa.post_id = p.id - and pa.post_id = OLD.post_id; +CREATE INDEX idx_comment_aggregates_controversy ON comment_aggregates (controversy_rank DESC); - END IF; - return null; -end $$; +-- Update post_aggregates_score trigger function to include controversy_rank update +CREATE OR REPLACE FUNCTION post_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + post_aggregates pa + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END, + controversy_rank = controversy_rank (pa.upvotes + CASE WHEN NEW.score = 1 THEN + 1 + ELSE + 0 + END::numeric, pa.downvotes + CASE WHEN NEW.score = - 1 THEN + 1 + ELSE + 0 + END::numeric) + WHERE + pa.post_id = NEW.post_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to post because that post may not exist anymore + UPDATE + post_aggregates pa + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END, + controversy_rank = controversy_rank (pa.upvotes + CASE WHEN NEW.score = 1 THEN + 1 + ELSE + 0 + END::numeric, pa.downvotes + CASE WHEN NEW.score = - 1 THEN + 1 + ELSE + 0 + END::numeric) + FROM + post p + WHERE + pa.post_id = p.id + AND pa.post_id = OLD.post_id; + END IF; + RETURN NULL; +END +$$; -- Update comment_aggregates_score trigger function to include controversy_rank update -create or replace function comment_aggregates_score() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - update comment_aggregates ca - set score = score + NEW.score, - upvotes = case when NEW.score = 1 then upvotes + 1 else upvotes end, - downvotes = case when NEW.score = -1 then downvotes + 1 else downvotes end, - controversy_rank = controversy_rank(ca.upvotes + case when NEW.score = 1 then 1 else 0 end::numeric, - ca.downvotes + case when NEW.score = -1 then 1 else 0 end::numeric) - where ca.comment_id = NEW.comment_id; - - ELSIF (TG_OP = 'DELETE') THEN - -- Join to comment because that comment may not exist anymore - update comment_aggregates ca - set score = score - OLD.score, - upvotes = case when OLD.score = 1 then upvotes - 1 else upvotes end, - downvotes = case when OLD.score = -1 then downvotes - 1 else downvotes end, - controversy_rank = controversy_rank(ca.upvotes + case when NEW.score = 1 then 1 else 0 end::numeric, - ca.downvotes + case when NEW.score = -1 then 1 else 0 end::numeric) - from comment c - where ca.comment_id = c.id - and ca.comment_id = OLD.comment_id; - - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION comment_aggregates_score () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + UPDATE + comment_aggregates ca + SET + score = score + NEW.score, + upvotes = CASE WHEN NEW.score = 1 THEN + upvotes + 1 + ELSE + upvotes + END, + downvotes = CASE WHEN NEW.score = - 1 THEN + downvotes + 1 + ELSE + downvotes + END, + controversy_rank = controversy_rank (ca.upvotes + CASE WHEN NEW.score = 1 THEN + 1 + ELSE + 0 + END::numeric, ca.downvotes + CASE WHEN NEW.score = - 1 THEN + 1 + ELSE + 0 + END::numeric) + WHERE + ca.comment_id = NEW.comment_id; + ELSIF (TG_OP = 'DELETE') THEN + -- Join to comment because that comment may not exist anymore + UPDATE + comment_aggregates ca + SET + score = score - OLD.score, + upvotes = CASE WHEN OLD.score = 1 THEN + upvotes - 1 + ELSE + upvotes + END, + downvotes = CASE WHEN OLD.score = - 1 THEN + downvotes - 1 + ELSE + downvotes + END, + controversy_rank = controversy_rank (ca.upvotes + CASE WHEN NEW.score = 1 THEN + 1 + ELSE + 0 + END::numeric, ca.downvotes + CASE WHEN NEW.score = - 1 THEN + 1 + ELSE + 0 + END::numeric) + FROM + comment c + WHERE + ca.comment_id = c.id + AND ca.comment_id = OLD.comment_id; + END IF; + RETURN NULL; +END +$$; diff --git a/migrations/2023-07-26-222023_site-aggregates-one/down.sql b/migrations/2023-07-26-222023_site-aggregates-one/down.sql index f384785f..90dbbd7f 100644 --- a/migrations/2023-07-26-222023_site-aggregates-one/down.sql +++ b/migrations/2023-07-26-222023_site-aggregates-one/down.sql @@ -1,11 +1,16 @@ -create or replace function site_aggregates_site() -returns trigger language plpgsql -as $$ -begin - IF (TG_OP = 'INSERT') THEN - insert into site_aggregates (site_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from site_aggregates where site_id = OLD.id; - END IF; - return null; -end $$; \ No newline at end of file +CREATE OR REPLACE FUNCTION site_aggregates_site () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + INSERT INTO site_aggregates (site_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM site_aggregates + WHERE site_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + diff --git a/migrations/2023-07-26-222023_site-aggregates-one/up.sql b/migrations/2023-07-26-222023_site-aggregates-one/up.sql index 7ed40316..7d3c6c9b 100644 --- a/migrations/2023-07-26-222023_site-aggregates-one/up.sql +++ b/migrations/2023-07-26-222023_site-aggregates-one/up.sql @@ -1,15 +1,32 @@ -create or replace function site_aggregates_site() -returns trigger language plpgsql -as $$ -begin - -- we only ever want to have a single value in site_aggregate because the site_aggregate triggers update all rows in that table. - -- a cleaner check would be to insert it for the local_site but that would break assumptions at least in the tests - IF (TG_OP = 'INSERT') AND NOT EXISTS (select id from site_aggregates limit 1) THEN - insert into site_aggregates (site_id) values (NEW.id); - ELSIF (TG_OP = 'DELETE') THEN - delete from site_aggregates where site_id = OLD.id; - END IF; - return null; -end $$; +CREATE OR REPLACE FUNCTION site_aggregates_site () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- we only ever want to have a single value in site_aggregate because the site_aggregate triggers update all rows in that table. + -- a cleaner check would be to insert it for the local_site but that would break assumptions at least in the tests + IF (TG_OP = 'INSERT') AND NOT EXISTS ( + SELECT + id + FROM + site_aggregates + LIMIT 1) THEN + INSERT INTO site_aggregates (site_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM site_aggregates + WHERE site_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + +DELETE FROM site_aggregates a +WHERE NOT EXISTS ( + SELECT + id + FROM + local_site s + WHERE + s.site_id = a.site_id); -delete from site_aggregates a where not exists (select id from local_site s where s.site_id = a.site_id); \ No newline at end of file diff --git a/migrations/2023-07-27-134652_remove-expensive-broken-trigger/down.sql b/migrations/2023-07-27-134652_remove-expensive-broken-trigger/down.sql index 1a5c4ec4..3db25c4b 100644 --- a/migrations/2023-07-27-134652_remove-expensive-broken-trigger/down.sql +++ b/migrations/2023-07-27-134652_remove-expensive-broken-trigger/down.sql @@ -1,80 +1,124 @@ -create or replace function person_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count + 1 where person_id = NEW.creator_id; - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count - 1 where person_id = OLD.creator_id; - +CREATE OR REPLACE FUNCTION person_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + comment_count = comment_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) 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 and c.deleted = 'f' and c.removed = 'f' - left join comment_like cl on c.id = cl.comment_id - group by u.id - ) cd - where ua.person_id = OLD.creator_id; + 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 + AND c.deleted = 'f' + AND c.removed = 'f' + 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 or replace function person_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count + 1 where person_id = NEW.creator_id; - - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count - 1 where person_id = OLD.creator_id; + RETURN NULL; +END +$$; +CREATE OR REPLACE FUNCTION person_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + post_count = post_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) 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 and p.deleted = 'f' and p.removed = 'f' - left join post_like pl on p.id = pl.post_id - group by u.id - ) pd - where ua.person_id = OLD.creator_id; - + 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 + AND p.deleted = 'f' + AND p.removed = 'f' + 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 $$; + RETURN NULL; +END +$$; -create or replace function community_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments + 1 from comment c, post p -where p.id = c.post_id - and p.id = NEW.post_id - and ca.community_id = p.community_id; -ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments - 1 from comment c, post p -where p.id = c.post_id - and p.id = OLD.post_id - and ca.community_id = p.community_id; +CREATE OR REPLACE FUNCTION community_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments + 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = NEW.post_id + AND ca.community_id = p.community_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments - 1 + FROM + comment c, + post p + WHERE + p.id = c.post_id + AND p.id = OLD.post_id + AND ca.community_id = p.community_id; + END IF; + RETURN NULL; +END +$$; -END IF; -return null; -end $$; \ No newline at end of file diff --git a/migrations/2023-07-27-134652_remove-expensive-broken-trigger/up.sql b/migrations/2023-07-27-134652_remove-expensive-broken-trigger/up.sql index 66a78371..90385dd6 100644 --- a/migrations/2023-07-27-134652_remove-expensive-broken-trigger/up.sql +++ b/migrations/2023-07-27-134652_remove-expensive-broken-trigger/up.sql @@ -1,47 +1,78 @@ -create or replace function person_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count + 1 where person_id = NEW.creator_id; - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set comment_count = comment_count - 1 where person_id = OLD.creator_id; +CREATE OR REPLACE FUNCTION person_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + comment_count = comment_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + comment_count = comment_count - 1 + WHERE + person_id = OLD.creator_id; END IF; - return null; -end $$; + RETURN NULL; +END +$$; -create or replace function person_aggregates_post_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count + 1 where person_id = NEW.creator_id; - - ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN - update person_aggregates - set post_count = post_count - 1 where person_id = OLD.creator_id; +CREATE OR REPLACE FUNCTION person_aggregates_post_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + post_count = post_count + 1 + WHERE + person_id = NEW.creator_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + person_aggregates + SET + post_count = post_count - 1 + WHERE + person_id = OLD.creator_id; END IF; - return null; -end $$; + RETURN NULL; +END +$$; -create or replace function community_aggregates_comment_count() - returns trigger language plpgsql -as $$ -begin - IF (was_restored_or_created(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments + 1 from post p -where p.id = NEW.post_id - and ca.community_id = p.community_id; -ELSIF (was_removed_or_deleted(TG_OP, OLD, NEW)) THEN -update community_aggregates ca -set comments = comments - 1 from post p -where p.id = OLD.post_id - and ca.community_id = p.community_id; +CREATE OR REPLACE FUNCTION community_aggregates_comment_count () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + IF (was_restored_or_created (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments + 1 + FROM + post p + WHERE + p.id = NEW.post_id + AND ca.community_id = p.community_id; + ELSIF (was_removed_or_deleted (TG_OP, OLD, NEW)) THEN + UPDATE + community_aggregates ca + SET + comments = comments - 1 + FROM + post p + WHERE + p.id = OLD.post_id + AND ca.community_id = p.community_id; + END IF; + RETURN NULL; +END +$$; -END IF; -return null; -end $$; \ No newline at end of file diff --git a/scripts/fix-clippy.sh b/scripts/lint.sh similarity index 87% rename from scripts/fix-clippy.sh rename to scripts/lint.sh index 5ad3ca8b..b06c5541 100755 --- a/scripts/fix-clippy.sh +++ b/scripts/lint.sh @@ -21,5 +21,11 @@ cargo clippy --workspace --fix --allow-staged --allow-dirty --tests --all-target -D clippy::unwrap_used \ -D clippy::indexing_slicing +# Format rust files cargo +nightly fmt + +# Format toml files taplo format + +# Format sql files +find migrations -type f -name '*.sql' -exec pg_format -i {} + diff --git a/scripts/sql_format_check.sh b/scripts/sql_format_check.sh new file mode 100755 index 00000000..8a92eefd --- /dev/null +++ b/scripts/sql_format_check.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +# This check is only used for CI. + +CWD="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" + +cd $CWD/../ + +find migrations -type f -name "*.sql" -print0 | while read -d $'\0' FILE +do + TMP_FILE="/tmp/tmp_pg_format.sql" + pg_format $FILE > $TMP_FILE + diff $FILE $TMP_FILE +done