]> Untitled Git - lemmy.git/blob - migrations/2020-12-03-035643_create_user_aggregates/up.sql
8d46fbfbee915bb2284655e4002555fc694250c7
[lemmy.git] / migrations / 2020-12-03-035643_create_user_aggregates / up.sql
1 -- Add user aggregates
2 create table user_aggregates (
3   id serial primary key,
4   user_id int references user_ on update cascade on delete cascade not null,
5   post_count bigint not null,
6   post_score bigint not null,
7   comment_count bigint not null,
8   comment_score bigint not null,
9   unique (user_id)
10 );
11
12 insert into user_aggregates (user_id, post_count, post_score, comment_count, comment_score)
13   select u.id,
14   coalesce(pd.posts, 0),
15   coalesce(pd.score, 0),
16   coalesce(cd.comments, 0),
17   coalesce(cd.score, 0)
18   from user_ u
19   left join (
20     select p.creator_id,
21       count(distinct p.id) as posts,
22       sum(pl.score) as score
23       from post p
24       left join post_like pl on p.id = pl.post_id
25       group by p.creator_id
26     ) pd on u.id = pd.creator_id
27   left join ( 
28     select c.creator_id,
29     count(distinct c.id) as comments,
30     sum(cl.score) as score
31     from comment c
32     left join comment_like cl on c.id = cl.comment_id
33     group by c.creator_id
34   ) cd on u.id = cd.creator_id;
35
36
37 -- Add user aggregate triggers
38 -- post count
39 create function user_aggregates_post_count()
40 returns trigger language plpgsql
41 as $$
42 begin
43   IF (TG_OP = 'INSERT') THEN
44     update user_aggregates 
45     set post_count = post_count + 1 where user_id = NEW.user_id;
46   ELSIF (TG_OP = 'DELETE') THEN
47     update user_aggregates 
48     set post_count = post_count - 1 where user_id = OLD.user_id;
49   END IF;
50   return null;
51 end $$;
52
53 create trigger user_aggregates_post_count
54 after insert or delete on post
55 execute procedure user_aggregates_post_count();
56
57 -- post score
58 create function user_aggregates_post_score()
59 returns trigger language plpgsql
60 as $$
61 begin
62   IF (TG_OP = 'INSERT') THEN
63     -- TODO not sure if this is working right
64     -- Need to get the post creator, not the voter
65     update user_aggregates 
66     set post_score = post_score + NEW.score
67     from post_like pl join post p on p.id = pl.post_id
68     where p.id = NEW.post_id and p.creator_id = NEW.user_id;
69   ELSIF (TG_OP = 'DELETE') THEN
70     update user_aggregates 
71     set post_score = post_score - OLD.score
72     from post_like pl join post p on p.id = pl.post_id
73     where p.id = OLD.post_id and p.creator_id = OLD.user_id;
74   END IF;
75   return null;
76 end $$;
77
78 create trigger user_aggregates_post_score
79 after insert or delete on post_like
80 execute procedure user_aggregates_post_score();
81
82 -- comment count
83 create function user_aggregates_comment_count()
84 returns trigger language plpgsql
85 as $$
86 begin
87   IF (TG_OP = 'INSERT') THEN
88     update user_aggregates 
89     set comment_count = comment_count + 1 where user_id = NEW.user_id;
90   ELSIF (TG_OP = 'DELETE') THEN
91     update user_aggregates 
92     set comment_count = comment_count - 1 where user_id = OLD.user_id;
93   END IF;
94   return null;
95 end $$;
96
97 create trigger user_aggregates_comment_count
98 after insert or delete on comment
99 execute procedure user_aggregates_comment_count();
100
101 -- comment score
102 create function user_aggregates_comment_score()
103 returns trigger language plpgsql
104 as $$
105 begin
106   IF (TG_OP = 'INSERT') THEN
107     -- Need to get the post creator, not the voter
108     update user_aggregates 
109     set comment_score = comment_score + NEW.score
110     from comment_like pl join comment p on p.id = pl.comment_id
111     where p.id = NEW.comment_id and p.creator_id = NEW.user_id;
112   ELSIF (TG_OP = 'DELETE') THEN
113     update user_aggregates 
114     set comment_score = comment_score - OLD.score
115     from comment_like pl join comment p on p.id = pl.comment_id
116     where p.id = OLD.comment_id and p.creator_id = OLD.user_id;
117   END IF;
118   return null;
119 end $$;
120
121 create trigger user_aggregates_comment_score
122 after insert or delete on comment_like
123 execute procedure user_aggregates_comment_score();