From 11f1de4bc772c2bb4cc37c69bfc033b6fbe2561d Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 14 Apr 2020 15:12:19 -0400 Subject: [PATCH] Updating views to add apub actor_id and local columns. --- .../down.sql | 440 ++++++++++++++++ .../up.sql | 497 ++++++++++++++++++ server/src/apub/mod.rs | 4 +- server/src/db/comment_view.rs | 42 ++ server/src/db/community_view.rs | 39 ++ server/src/db/post_view.rs | 30 ++ server/src/db/user_mention_view.rs | 18 + server/src/db/user_view.rs | 9 + ui/src/interfaces.ts | 26 + 9 files changed, 1104 insertions(+), 1 deletion(-) create mode 100644 server/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql create mode 100644 server/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql diff --git a/server/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql b/server/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql new file mode 100644 index 000000000..ce2dde39e --- /dev/null +++ b/server/migrations/2020-04-14-163701_update_views_for_activitypub/down.sql @@ -0,0 +1,440 @@ +-- 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); + +-- 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 +) + +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 +; + +-- 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; + +-- post_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 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 +; + + +-- 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; + +-- 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.*, +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 +) +select cv.*, +closereply.recipient_id +from comment_mview cv, closereply +where closereply.id = cv.id +; + +-- user mention +create view user_mention_view as +select + c.id, + um.id as user_mention_id, + c.creator_id, + c.post_id, + c.parent_id, + c.content, + c.removed, + um.read, + c.published, + c.updated, + c.deleted, + c.community_id, + c.community_name, + c.banned, + c.banned_from_community, + c.creator_name, + c.creator_avatar, + c.score, + c.upvotes, + c.downvotes, + c.hot_rank, + c.user_id, + 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 +) + +select + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.community_name, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + 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, + 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 + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.community_name, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + ac.upvotes, + ac.downvotes, + ac.hot_rank, + 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 +; + diff --git a/server/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql b/server/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql new file mode 100644 index 000000000..02499fc24 --- /dev/null +++ b/server/migrations/2020-04-14-163701_update_views_for_activitypub/up.sql @@ -0,0 +1,497 @@ +-- 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); + +-- community_view +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 +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 +; + +-- 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; + +-- post_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 +) +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; + +-- 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.*, +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 + 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 +) +select cv.*, +closereply.recipient_id +from comment_mview cv, closereply +where closereply.id = cv.id +; + +-- user mention +create view user_mention_view as +select + c.id, + um.id as user_mention_id, + c.creator_id, + c.creator_actor_id, + c.creator_local, + c.post_id, + c.parent_id, + c.content, + c.removed, + um.read, + c.published, + c.updated, + c.deleted, + c.community_id, + c.community_actor_id, + c.community_local, + c.community_name, + c.banned, + c.banned_from_community, + c.creator_name, + c.creator_avatar, + c.score, + c.upvotes, + c.downvotes, + c.hot_rank, + c.user_id, + 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 + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.creator_actor_id, + ac.creator_local, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.community_actor_id, + ac.community_local, + ac.community_name, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + 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, + 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 + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.creator_actor_id, + ac.creator_local, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.community_actor_id, + ac.community_local, + ac.community_name, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + ac.upvotes, + ac.downvotes, + ac.hot_rank, + 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 +; + diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index 68839c39f..c1716ca27 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -47,7 +47,9 @@ pub fn make_apub_endpoint(endpoint_type: EndpointType, name: &str) -> Url { EndpointType::Community => "c", EndpointType::User => "u", EndpointType::Post => "p", - EndpointType::Comment => todo!(), + // TODO I have to change this else my update advanced_migrations crashes the + // server if a comment exists. + EndpointType::Comment => "comment", }; Url::parse(&format!( diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs index 11507dcd3..f0b97cb51 100644 --- a/server/src/db/comment_view.rs +++ b/server/src/db/comment_view.rs @@ -14,10 +14,16 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + ap_id -> Text, + local -> Bool, community_id -> Int4, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, banned -> Bool, banned_from_community -> Bool, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, score -> BigInt, @@ -43,10 +49,16 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + ap_id -> Text, + local -> Bool, community_id -> Int4, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, banned -> Bool, banned_from_community -> Bool, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, score -> BigInt, @@ -75,10 +87,16 @@ pub struct CommentView { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub ap_id: String, + pub local: bool, pub community_id: i32, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, pub banned: bool, pub banned_from_community: bool, + pub creator_actor_id: String, + pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, pub score: i64, @@ -282,10 +300,16 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + ap_id -> Text, + local -> Bool, community_id -> Int4, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, banned -> Bool, banned_from_community -> Bool, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, score -> BigInt, @@ -315,10 +339,16 @@ pub struct ReplyView { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub ap_id: String, + pub local: bool, pub community_id: i32, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, pub banned: bool, pub banned_from_community: bool, + pub creator_actor_id: String, + pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, pub score: i64, @@ -551,6 +581,12 @@ mod tests { my_vote: None, subscribed: None, saved: None, + ap_id: "changeme".to_string(), + local: true, + community_actor_id: inserted_community.actor_id.to_owned(), + community_local: true, + creator_actor_id: inserted_user.actor_id.to_owned(), + creator_local: true, }; let expected_comment_view_with_user = CommentView { @@ -578,6 +614,12 @@ mod tests { my_vote: Some(1), subscribed: None, saved: None, + ap_id: "changeme".to_string(), + local: true, + community_actor_id: inserted_community.actor_id.to_owned(), + community_local: true, + creator_actor_id: inserted_user.actor_id.to_owned(), + creator_local: true, }; let mut read_comment_views_no_user = CommentQueryBuilder::create(&conn) diff --git a/server/src/db/community_view.rs b/server/src/db/community_view.rs index f24c922c3..3e946f472 100644 --- a/server/src/db/community_view.rs +++ b/server/src/db/community_view.rs @@ -15,6 +15,11 @@ table! { updated -> Nullable, deleted -> Bool, nsfw -> Bool, + actor_id -> Text, + local -> Bool, + last_refreshed_at -> Timestamp, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, category_name -> Varchar, @@ -40,6 +45,11 @@ table! { updated -> Nullable, deleted -> Bool, nsfw -> Bool, + actor_id -> Text, + local -> Bool, + last_refreshed_at -> Timestamp, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, category_name -> Varchar, @@ -58,8 +68,12 @@ table! { community_id -> Int4, user_id -> Int4, published -> Timestamp, + user_actor_id -> Text, + user_local -> Bool, user_name -> Varchar, avatar -> Nullable, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, } } @@ -70,8 +84,12 @@ table! { community_id -> Int4, user_id -> Int4, published -> Timestamp, + user_actor_id -> Text, + user_local -> Bool, user_name -> Varchar, avatar -> Nullable, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, } } @@ -82,8 +100,12 @@ table! { community_id -> Int4, user_id -> Int4, published -> Timestamp, + user_actor_id -> Text, + user_local -> Bool, user_name -> Varchar, avatar -> Nullable, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, } } @@ -104,6 +126,11 @@ pub struct CommunityView { pub updated: Option, pub deleted: bool, pub nsfw: bool, + pub actor_id: String, + pub local: bool, + pub last_refreshed_at: chrono::NaiveDateTime, + pub creator_actor_id: String, + pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, pub category_name: String, @@ -257,8 +284,12 @@ pub struct CommunityModeratorView { pub community_id: i32, pub user_id: i32, pub published: chrono::NaiveDateTime, + pub user_actor_id: String, + pub user_local: bool, pub user_name: String, pub avatar: Option, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, } @@ -287,8 +318,12 @@ pub struct CommunityFollowerView { pub community_id: i32, pub user_id: i32, pub published: chrono::NaiveDateTime, + pub user_actor_id: String, + pub user_local: bool, pub user_name: String, pub avatar: Option, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, } @@ -317,8 +352,12 @@ pub struct CommunityUserBanView { pub community_id: i32, pub user_id: i32, pub published: chrono::NaiveDateTime, + pub user_actor_id: String, + pub user_local: bool, pub user_name: String, pub avatar: Option, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, } diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs index 3c155b007..a7ac58c03 100644 --- a/server/src/db/post_view.rs +++ b/server/src/db/post_view.rs @@ -22,10 +22,16 @@ table! { embed_description -> Nullable, embed_html -> Nullable, thumbnail_url -> Nullable, + ap_id -> Text, + local -> Bool, banned -> Bool, banned_from_community -> Bool, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, community_removed -> Bool, community_deleted -> Bool, @@ -63,10 +69,16 @@ table! { embed_description -> Nullable, embed_html -> Nullable, thumbnail_url -> Nullable, + ap_id -> Text, + local -> Bool, banned -> Bool, banned_from_community -> Bool, + creator_actor_id -> Text, + creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, community_removed -> Bool, community_deleted -> Bool, @@ -107,10 +119,16 @@ pub struct PostView { pub embed_description: Option, pub embed_html: Option, pub thumbnail_url: Option, + pub ap_id: String, + pub local: bool, pub banned: bool, pub banned_from_community: bool, + pub creator_actor_id: String, + pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, pub community_removed: bool, pub community_deleted: bool, @@ -487,6 +505,12 @@ mod tests { embed_description: None, embed_html: None, thumbnail_url: None, + ap_id: "changeme".to_string(), + local: true, + creator_actor_id: inserted_user.actor_id.to_owned(), + creator_local: true, + community_actor_id: inserted_community.actor_id.to_owned(), + community_local: true, }; let expected_post_listing_with_user = PostView { @@ -526,6 +550,12 @@ mod tests { embed_description: None, embed_html: None, thumbnail_url: None, + ap_id: "changeme".to_string(), + local: true, + creator_actor_id: inserted_user.actor_id.to_owned(), + creator_local: true, + community_actor_id: inserted_community.actor_id.to_owned(), + community_local: true, }; let read_post_listings_with_user = PostQueryBuilder::create(&conn) diff --git a/server/src/db/user_mention_view.rs b/server/src/db/user_mention_view.rs index 8046747e6..85fd760fc 100644 --- a/server/src/db/user_mention_view.rs +++ b/server/src/db/user_mention_view.rs @@ -7,6 +7,8 @@ table! { id -> Int4, user_mention_id -> Int4, creator_id -> Int4, + creator_actor_id -> Text, + creator_local -> Bool, post_id -> Int4, parent_id -> Nullable, content -> Text, @@ -16,6 +18,8 @@ table! { updated -> Nullable, deleted -> Bool, community_id -> Int4, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, banned -> Bool, banned_from_community -> Bool, @@ -29,6 +33,8 @@ table! { my_vote -> Nullable, saved -> Nullable, recipient_id -> Int4, + recipient_actor_id -> Text, + recipient_local -> Bool, } } @@ -37,6 +43,8 @@ table! { id -> Int4, user_mention_id -> Int4, creator_id -> Int4, + creator_actor_id -> Text, + creator_local -> Bool, post_id -> Int4, parent_id -> Nullable, content -> Text, @@ -46,6 +54,8 @@ table! { updated -> Nullable, deleted -> Bool, community_id -> Int4, + community_actor_id -> Text, + community_local -> Bool, community_name -> Varchar, banned -> Bool, banned_from_community -> Bool, @@ -59,6 +69,8 @@ table! { my_vote -> Nullable, saved -> Nullable, recipient_id -> Int4, + recipient_actor_id -> Text, + recipient_local -> Bool, } } @@ -70,6 +82,8 @@ pub struct UserMentionView { pub id: i32, pub user_mention_id: i32, pub creator_id: i32, + pub creator_actor_id: String, + pub creator_local: bool, pub post_id: i32, pub parent_id: Option, pub content: String, @@ -79,6 +93,8 @@ pub struct UserMentionView { pub updated: Option, pub deleted: bool, pub community_id: i32, + pub community_actor_id: String, + pub community_local: bool, pub community_name: String, pub banned: bool, pub banned_from_community: bool, @@ -92,6 +108,8 @@ pub struct UserMentionView { pub my_vote: Option, pub saved: Option, pub recipient_id: i32, + pub recipient_actor_id: String, + pub recipient_local: bool, } pub struct UserMentionQueryBuilder<'a> { diff --git a/server/src/db/user_view.rs b/server/src/db/user_view.rs index efd844685..88cbb7fb6 100644 --- a/server/src/db/user_view.rs +++ b/server/src/db/user_view.rs @@ -5,10 +5,13 @@ use diesel::pg::Pg; table! { user_view (id) { id -> Int4, + actor_id -> Text, name -> Varchar, avatar -> Nullable, email -> Nullable, matrix_user_id -> Nullable, + bio -> Nullable, + local -> Bool, admin -> Bool, banned -> Bool, show_avatars -> Bool, @@ -24,10 +27,13 @@ table! { table! { user_mview (id) { id -> Int4, + actor_id -> Text, name -> Varchar, avatar -> Nullable, email -> Nullable, matrix_user_id -> Nullable, + bio -> Nullable, + local -> Bool, admin -> Bool, banned -> Bool, show_avatars -> Bool, @@ -46,10 +52,13 @@ table! { #[table_name = "user_view"] pub struct UserView { pub id: i32, + pub actor_id: String, pub name: String, pub avatar: Option, pub email: Option, pub matrix_user_id: Option, + pub bio: Option, + pub local: bool, pub admin: bool, pub banned: bool, pub show_avatars: bool, diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index 283e1944f..b98425161 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -98,10 +98,13 @@ export interface User { export interface UserView { id: number; + actor_id: string; name: string; avatar?: string; email?: string; matrix_user_id?: string; + bio?: string; + local: boolean; published: string; number_of_posts: number; post_score: number; @@ -115,15 +118,21 @@ export interface UserView { export interface CommunityUser { id: number; user_id: number; + user_actor_id: string; + user_local: boolean; user_name: string; avatar?: string; community_id: number; + community_actor_id: string; + community_local: boolean; community_name: string; published: string; } export interface Community { id: number; + actor_id: string; + local: boolean; name: string; title: string; description?: string; @@ -134,6 +143,9 @@ export interface Community { nsfw: boolean; published: string; updated?: string; + creator_actor_id: string; + creator_local: boolean; + last_refreshed_at: string; creator_name: string; creator_avatar?: string; category_name: string; @@ -159,13 +171,19 @@ export interface Post { embed_description?: string; embed_html?: string; thumbnail_url?: string; + ap_id: string; + local: boolean; nsfw: boolean; banned: boolean; banned_from_community: boolean; published: string; updated?: string; + creator_actor_id: string; + creator_local: boolean; creator_name: string; creator_avatar?: string; + community_actor_id: string; + community_local: boolean; community_name: string; community_removed: boolean; community_deleted: boolean; @@ -186,6 +204,8 @@ export interface Post { export interface Comment { id: number; + ap_id: string; + local: boolean; creator_id: number; post_id: number; parent_id?: number; @@ -196,9 +216,13 @@ export interface Comment { published: string; updated?: string; community_id: number; + community_actor_id: string; + community_local: boolean; community_name: string; banned: boolean; banned_from_community: boolean; + creator_actor_id: string; + creator_local: boolean; creator_name: string; creator_avatar?: string; score: number; @@ -211,6 +235,8 @@ export interface Comment { saved?: boolean; user_mention_id?: number; // For mention type recipient_id?: number; + recipient_actor_id?: string; + recipient_local?: boolean; depth?: number; }