]> Untitled Git - lemmy.git/blob - server/migrations_testing/2020-01-13-025151_create_materialized_views/up.sql
routes.api: fix get_captcha endpoint (#1135)
[lemmy.git] / server / migrations_testing / 2020-01-13-025151_create_materialized_views / up.sql
1 -- post
2 drop view post_view;
3 create materialized view post_view as
4 with all_post as
5 (
6   select        
7   p.*,
8   (select u.banned from user_ u where p.creator_id = u.id) as banned,
9   (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,
10   (select name from user_ where p.creator_id = user_.id) as creator_name,
11   (select avatar from user_ where p.creator_id = user_.id) as creator_avatar,
12   (select name from community where p.community_id = community.id) as community_name,
13   (select removed from community c where p.community_id = c.id) as community_removed,
14   (select deleted from community c where p.community_id = c.id) as community_deleted,
15   (select nsfw from community c where p.community_id = c.id) as community_nsfw,
16   (select count(*) from comment where comment.post_id = p.id) as number_of_comments,
17   coalesce(sum(pl.score), 0) as score,
18   count (case when pl.score = 1 then 1 else null end) as upvotes,
19   count (case when pl.score = -1 then 1 else null end) as downvotes,
20   hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank
21   from post p
22   left join post_like pl on p.id = pl.post_id
23   group by p.id
24 )
25
26 select
27 ap.*,
28 u.id as user_id,
29 coalesce(pl.score, 0) as my_vote,
30 (select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed,
31 (select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read,
32 (select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved
33 from user_ u
34 cross join all_post ap
35 left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id
36
37 union all
38
39 select 
40 ap.*,
41 null as user_id,
42 null as my_vote,
43 null as subscribed,
44 null as read,
45 null as saved
46 from all_post ap
47 with data
48 ;
49
50 create unique index idx_post_view_unique on post_view (id, user_id); 
51 create index idx_post_view_user_id on post_view (user_id);
52 create index idx_post_view_hot_rank_published on post_view (hot_rank desc, published desc);
53 create index idx_post_view_published on post_view (published desc);
54 create index idx_post_view_score on post_view (score desc);
55
56 -- user_view
57 drop view user_view;
58 create materialized view user_view as 
59 select id,
60 name,
61 avatar,
62 email,
63 fedi_name,
64 admin,
65 banned,
66 show_avatars,
67 send_notifications_to_email,
68 published,
69 (select count(*) from post p where p.creator_id = u.id) as number_of_posts,
70 (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,
71 (select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
72 (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
73 from user_ u;
74
75 create unique index idx_user_view_unique on user_view (id); 
76 create index idx_user_view_comment_published on user_view (comment_score desc, published desc);
77 create index idx_user_view_admin on user_view (admin);
78 create index idx_user_view_banned on user_view (banned);
79
80 -- community
81 drop view community_view;
82 create materialized view community_view as 
83 with all_community as
84 (
85   select *,
86   (select name from user_ u where c.creator_id = u.id) as creator_name,
87   (select avatar from user_ u where c.creator_id = u.id) as creator_avatar,
88   (select name from category ct where c.category_id = ct.id) as category_name,
89   (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers,
90   (select count(*) from post p where p.community_id = c.id) as number_of_posts,
91   (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments,
92   hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank
93   from community c
94 )
95
96 select
97 ac.*,
98 u.id as user_id,
99 (select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed
100 from user_ u
101 cross join all_community ac
102
103 union all
104
105 select 
106 ac.*,
107 null as user_id,
108 null as subscribed
109 from all_community ac
110 ;
111
112 create unique index idx_community_view_unique on community_view (id, user_id); 
113 create index idx_community_view_user_id on community_view (user_id);
114 create index idx_community_view_hot_rank_subscribed on community_view (hot_rank desc, number_of_subscribers desc);
115
116
117 -- reply and comment view
118 drop view reply_view;
119 drop view user_mention_view;
120 drop view comment_view;
121 create materialized view comment_view as
122 with all_comment as
123 (
124   select        
125   c.*,
126   (select community_id from post p where p.id = c.post_id),
127   (select u.banned from user_ u where c.creator_id = u.id) as banned,
128   (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,
129   (select name from user_ where c.creator_id = user_.id) as creator_name,
130   (select avatar from user_ where c.creator_id = user_.id) as creator_avatar,
131   coalesce(sum(cl.score), 0) as score,
132   count (case when cl.score = 1 then 1 else null end) as upvotes,
133   count (case when cl.score = -1 then 1 else null end) as downvotes
134   from comment c
135   left join comment_like cl on c.id = cl.comment_id
136   group by c.id
137 )
138
139 select
140 ac.*,
141 u.id as user_id,
142 coalesce(cl.score, 0) as my_vote,
143 (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved
144 from user_ u
145 cross join all_comment ac
146 left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id
147
148 union all
149
150 select 
151     ac.*,
152     null as user_id, 
153     null as my_vote,
154     null as saved
155 from all_comment ac
156 ;
157
158 create unique index idx_comment_view_unique on comment_view (id, user_id); 
159 create index idx_comment_view_user_id on comment_view (user_id);
160 create index idx_comment_view_creator_id on comment_view (creator_id);
161 create index idx_comment_view_post_id on comment_view (post_id);
162 create index idx_comment_view_score on comment_view (score desc);
163
164 create view reply_view as 
165 with closereply as (
166     select 
167     c2.id, 
168     c2.creator_id as sender_id, 
169     c.creator_id as recipient_id
170     from comment c
171     inner join comment c2 on c.id = c2.parent_id
172     where c2.creator_id != c.creator_id
173     -- Do union where post is null
174     union
175     select
176     c.id,
177     c.creator_id as sender_id,
178     p.creator_id as recipient_id
179     from comment c, post p
180     where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id
181 )
182 select cv.*,
183 closereply.recipient_id
184 from comment_view cv, closereply
185 where closereply.id = cv.id
186 ;
187
188 -- user mention
189 create view user_mention_view as
190 select 
191     c.id,
192     um.id as user_mention_id,
193     c.creator_id,
194     c.post_id,
195     c.parent_id,
196     c.content,
197     c.removed,
198     um.read,
199     c.published,
200     c.updated,
201     c.deleted,
202     c.community_id,
203     c.banned,
204     c.banned_from_community,
205     c.creator_name,
206     c.creator_avatar,
207     c.score,
208     c.upvotes,
209     c.downvotes,
210     c.user_id,
211     c.my_vote,
212     c.saved,
213     um.recipient_id
214 from user_mention um, comment_view c
215 where um.comment_id = c.id;
216
217 -- user
218 create or replace function refresh_user()
219 returns trigger language plpgsql
220 as $$
221 begin
222   refresh materialized view concurrently comment_view; -- cause of bans
223   refresh materialized view concurrently post_view;
224   return null;
225 end $$;
226
227 create trigger refresh_user
228 after insert or update or delete or truncate
229 on user_
230 for each statement
231 execute procedure refresh_user();
232
233 -- post
234 create or replace function refresh_post()
235 returns trigger language plpgsql
236 as $$
237 begin
238   refresh materialized view concurrently post_view; 
239   return null;
240 end $$;
241
242 create trigger refresh_post
243 after insert or update or delete or truncate
244 on post
245 for each statement
246 execute procedure refresh_post();
247
248 -- post_like
249 create or replace function refresh_post_like()
250 returns trigger language plpgsql
251 as $$
252 begin
253   refresh materialized view concurrently post_view;
254   return null;
255 end $$;
256
257 create trigger refresh_post_like
258 after insert or update or delete or truncate
259 on post_like
260 for each statement
261 execute procedure refresh_post_like();
262
263 -- community
264 create or replace function refresh_community()
265 returns trigger language plpgsql
266 as $$
267 begin
268   refresh materialized view concurrently post_view;
269   refresh materialized view concurrently community_view; 
270   return null;
271 end $$;
272
273 create trigger refresh_community
274 after insert or update or delete or truncate
275 on community
276 for each statement
277 execute procedure refresh_community();
278
279 -- community_follower
280 create or replace function refresh_community_follower()
281 returns trigger language plpgsql
282 as $$
283 begin
284   refresh materialized view concurrently community_view;
285   refresh materialized view concurrently post_view;
286   return null;
287 end $$;
288
289 create trigger refresh_community_follower
290 after insert or update or delete or truncate
291 on community_follower
292 for each statement
293 execute procedure refresh_community_follower();
294
295 -- comment
296 create or replace function refresh_comment()
297 returns trigger language plpgsql
298 as $$
299 begin
300   refresh materialized view concurrently post_view;
301   refresh materialized view concurrently comment_view; 
302   return null;
303 end $$;
304
305 create trigger refresh_comment
306 after insert or update or delete or truncate
307 on comment
308 for each statement
309 execute procedure refresh_comment();
310
311 -- comment_like
312 create or replace function refresh_comment_like()
313 returns trigger language plpgsql
314 as $$
315 begin
316   refresh materialized view concurrently comment_view;
317   return null;
318 end $$;
319
320 create trigger refresh_comment_like
321 after insert or update or delete or truncate
322 on comment_like
323 for each statement
324 execute procedure refresh_comment_like();