mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-23 03:11:32 +00:00
Adding views and replaceable schema.
This commit is contained in:
parent
724856d684
commit
1053df1a4b
7 changed files with 155 additions and 162 deletions
|
@ -7,7 +7,11 @@ use lemmy_db_schema::{
|
||||||
PostListingMode,
|
PostListingMode,
|
||||||
PostSortType,
|
PostSortType,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{CommentView, LocalImageView, PostView};
|
use lemmy_db_views::structs::{
|
||||||
|
LocalImageView,
|
||||||
|
ProfileCombinedPaginationCursor,
|
||||||
|
ProfileCombinedView,
|
||||||
|
};
|
||||||
use lemmy_db_views_actor::structs::{
|
use lemmy_db_views_actor::structs::{
|
||||||
CommentReplyView,
|
CommentReplyView,
|
||||||
CommunityModeratorView,
|
CommunityModeratorView,
|
||||||
|
@ -223,15 +227,13 @@ pub struct GetPersonDetails {
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
pub username: Option<String>,
|
pub username: Option<String>,
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
pub sort: Option<PostSortType>,
|
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
|
||||||
pub page: Option<i64>,
|
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
|
||||||
pub limit: Option<i64>,
|
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
|
||||||
pub community_id: Option<CommunityId>,
|
pub community_id: Option<CommunityId>,
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
pub saved_only: Option<bool>,
|
pub saved_only: Option<bool>,
|
||||||
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
|
pub page_cursor: Option<ProfileCombinedPaginationCursor>,
|
||||||
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
|
pub page_back: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
|
@ -243,8 +245,7 @@ pub struct GetPersonDetailsResponse {
|
||||||
pub person_view: PersonView,
|
pub person_view: PersonView,
|
||||||
#[cfg_attr(feature = "full", ts(optional))]
|
#[cfg_attr(feature = "full", ts(optional))]
|
||||||
pub site: Option<Site>,
|
pub site: Option<Site>,
|
||||||
pub comments: Vec<CommentView>,
|
pub content: Vec<ProfileCombinedView>,
|
||||||
pub posts: Vec<PostView>,
|
|
||||||
pub moderates: Vec<CommunityModeratorView>,
|
pub moderates: Vec<CommunityModeratorView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ use lemmy_api_common::{
|
||||||
person::{GetPersonDetails, GetPersonDetailsResponse},
|
person::{GetPersonDetails, GetPersonDetailsResponse},
|
||||||
utils::{check_private_instance, read_site_for_actor},
|
utils::{check_private_instance, read_site_for_actor},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::person::Person, utils::post_to_comment_sort_type};
|
use lemmy_db_schema::source::person::Person;
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
comment_view::CommentQuery,
|
profile_combined_view::ProfileCombinedQuery,
|
||||||
post_view::PostQuery,
|
|
||||||
structs::{LocalUserView, SiteView},
|
structs::{LocalUserView, SiteView},
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonView};
|
||||||
|
@ -47,46 +46,38 @@ pub async fn read_person(
|
||||||
// `my_user`
|
// `my_user`
|
||||||
let person_view = PersonView::read(&mut context.pool(), person_details_id).await?;
|
let person_view = PersonView::read(&mut context.pool(), person_details_id).await?;
|
||||||
|
|
||||||
let sort = data.sort;
|
// parse pagination token
|
||||||
let page = data.page;
|
let page_after = if let Some(pa) = &data.page_cursor {
|
||||||
let limit = data.limit;
|
Some(pa.read(&mut context.pool()).await?)
|
||||||
let saved_only = data.saved_only;
|
|
||||||
let community_id = data.community_id;
|
|
||||||
// If its saved only, you don't care what creator it was
|
|
||||||
// Or, if its not saved, then you only want it for that specific creator
|
|
||||||
let creator_id = if !saved_only.unwrap_or_default() {
|
|
||||||
Some(person_details_id)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
let page_back = data.page_back;
|
||||||
|
let saved_only = data.saved_only;
|
||||||
|
let community_id = data.community_id;
|
||||||
|
|
||||||
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
// If its saved only, then ignore the person details id,
|
||||||
|
// and use your local user's id
|
||||||
|
let creator_id = if !saved_only.unwrap_or_default() {
|
||||||
|
Some(person_details_id)
|
||||||
|
} else {
|
||||||
|
local_user_view.as_ref().map(|u| u.local_user.person_id)
|
||||||
|
};
|
||||||
|
|
||||||
let posts = PostQuery {
|
let content = if let Some(creator_id) = creator_id {
|
||||||
sort,
|
ProfileCombinedQuery {
|
||||||
saved_only,
|
|
||||||
local_user,
|
|
||||||
community_id,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
creator_id,
|
creator_id,
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.list(&local_site.site, &mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let comments = CommentQuery {
|
|
||||||
local_user,
|
|
||||||
sort: sort.map(post_to_comment_sort_type),
|
|
||||||
saved_only,
|
|
||||||
community_id,
|
community_id,
|
||||||
page,
|
saved_only,
|
||||||
limit,
|
page_after,
|
||||||
creator_id,
|
page_back,
|
||||||
..Default::default()
|
|
||||||
}
|
}
|
||||||
.list(&local_site.site, &mut context.pool())
|
.list(&mut context.pool(), &local_user_view)
|
||||||
.await?;
|
.await?
|
||||||
|
} else {
|
||||||
|
// if the creator is missing (saved_only, and no local_user), then return empty content
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
let moderates = CommunityModeratorView::for_person(
|
let moderates = CommunityModeratorView::for_person(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
@ -97,12 +88,10 @@ pub async fn read_person(
|
||||||
|
|
||||||
let site = read_site_for_actor(person_view.person.actor_id.clone(), &context).await?;
|
let site = read_site_for_actor(person_view.person.actor_id.clone(), &context).await?;
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(Json(GetPersonDetailsResponse {
|
Ok(Json(GetPersonDetailsResponse {
|
||||||
person_view,
|
person_view,
|
||||||
site,
|
site,
|
||||||
moderates,
|
moderates,
|
||||||
comments,
|
content,
|
||||||
posts,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,3 +685,31 @@ CALL r.create_report_combined_trigger ('comment_report');
|
||||||
|
|
||||||
CALL r.create_report_combined_trigger ('private_message_report');
|
CALL r.create_report_combined_trigger ('private_message_report');
|
||||||
|
|
||||||
|
-- Profile (comment, post)
|
||||||
|
CREATE PROCEDURE r.create_profile_combined_trigger (table_name text)
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $a$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE replace($b$ CREATE FUNCTION r.profile_combined_thing_insert ( )
|
||||||
|
RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO profile_combined (published, thing_id)
|
||||||
|
VALUES (NEW.published, NEW.id);
|
||||||
|
RETURN NEW;
|
||||||
|
END $$;
|
||||||
|
CREATE TRIGGER profile_combined
|
||||||
|
AFTER INSERT ON thing
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION r.profile_combined_thing_insert ( );
|
||||||
|
$b$,
|
||||||
|
'thing',
|
||||||
|
table_name);
|
||||||
|
END;
|
||||||
|
$a$;
|
||||||
|
|
||||||
|
CALL r.create_profile_combined_trigger ('post');
|
||||||
|
|
||||||
|
CALL r.create_profile_combined_trigger ('comment');
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,15 @@ use diesel::{
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
use i_love_jesus::PaginatedQueryBuilder;
|
use i_love_jesus::PaginatedQueryBuilder;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aliases::{self, creator_community_actions},
|
aliases::creator_community_actions,
|
||||||
newtypes::CommunityId,
|
newtypes::{CommunityId, PersonId},
|
||||||
schema::{
|
schema::{
|
||||||
comment,
|
comment,
|
||||||
comment_actions,
|
comment_actions,
|
||||||
comment_aggregates,
|
comment_aggregates,
|
||||||
community,
|
community,
|
||||||
community_actions,
|
community_actions,
|
||||||
|
image_details,
|
||||||
local_user,
|
local_user,
|
||||||
person,
|
person,
|
||||||
person_actions,
|
person_actions,
|
||||||
|
@ -74,11 +75,11 @@ impl ProfileCombinedPaginationCursor {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PaginationCursorData(ProfileCombined);
|
pub struct PaginationCursorData(ProfileCombined);
|
||||||
|
|
||||||
// TODO check these
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ProfileCombinedQuery {
|
pub struct ProfileCombinedQuery {
|
||||||
|
pub creator_id: PersonId,
|
||||||
pub community_id: Option<CommunityId>,
|
pub community_id: Option<CommunityId>,
|
||||||
pub unresolved_only: Option<bool>,
|
pub saved_only: Option<bool>,
|
||||||
pub page_after: Option<PaginationCursorData>,
|
pub page_after: Option<PaginationCursorData>,
|
||||||
pub page_back: Option<bool>,
|
pub page_back: Option<bool>,
|
||||||
}
|
}
|
||||||
|
@ -87,10 +88,12 @@ impl ProfileCombinedQuery {
|
||||||
pub async fn list(
|
pub async fn list(
|
||||||
self,
|
self,
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
user: &LocalUserView,
|
user: &Option<LocalUserView>,
|
||||||
) -> LemmyResult<Vec<ProfileCombinedView>> {
|
) -> LemmyResult<Vec<ProfileCombinedView>> {
|
||||||
let my_person_id = user.local_user.person_id;
|
let my_person_id = user
|
||||||
// let item_creator = aliases::person1.field(person::id);
|
.as_ref()
|
||||||
|
.map(|u| u.local_user.person_id)
|
||||||
|
.unwrap_or(PersonId(-1));
|
||||||
let item_creator = person::id;
|
let item_creator = person::id;
|
||||||
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
@ -114,20 +117,11 @@ impl ProfileCombinedQuery {
|
||||||
// The item creator
|
// The item creator
|
||||||
.inner_join(
|
.inner_join(
|
||||||
person::table.on(
|
person::table.on(
|
||||||
post::creator_id
|
comment::creator_id
|
||||||
.eq(person::id)
|
.eq(person::id)
|
||||||
.or(comment::creator_id.eq(person::id)),
|
.or(post::creator_id.eq(person::id)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// The item creator
|
|
||||||
// You can now use aliases::person1.field(person::id) / item_creator for all the item actions
|
|
||||||
// .inner_join(
|
|
||||||
// aliases::person1.on(
|
|
||||||
// post::creator_id
|
|
||||||
// .eq(item_creator)
|
|
||||||
// .or(comment::creator_id.eq(item_creator)),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// The community
|
// The community
|
||||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||||
.left_join(actions_alias(
|
.left_join(actions_alias(
|
||||||
|
@ -153,10 +147,7 @@ impl ProfileCombinedQuery {
|
||||||
Some(my_person_id),
|
Some(my_person_id),
|
||||||
item_creator,
|
item_creator,
|
||||||
))
|
))
|
||||||
.left_join(
|
.inner_join(post_aggregates::table.on(post::id.eq(post_aggregates::post_id)))
|
||||||
post_aggregates::table
|
|
||||||
.on(profile_combined::post_id.eq(post_aggregates::post_id.nullable())),
|
|
||||||
)
|
|
||||||
.left_join(
|
.left_join(
|
||||||
comment_aggregates::table
|
comment_aggregates::table
|
||||||
.on(profile_combined::comment_id.eq(comment_aggregates::comment_id.nullable())),
|
.on(profile_combined::comment_id.eq(comment_aggregates::comment_id.nullable())),
|
||||||
|
@ -166,43 +157,42 @@ impl ProfileCombinedQuery {
|
||||||
Some(my_person_id),
|
Some(my_person_id),
|
||||||
comment::id,
|
comment::id,
|
||||||
))
|
))
|
||||||
|
.left_join(image_details::table.on(post::thumbnail_url.eq(image_details::link.nullable())))
|
||||||
|
// The creator id filter
|
||||||
|
.filter(item_creator.eq(self.creator_id))
|
||||||
.select((
|
.select((
|
||||||
// Post-specific
|
// Post-specific
|
||||||
post::all_columns.nullable(),
|
post_aggregates::all_columns,
|
||||||
// post_aggregates::all_columns.nullable(),
|
coalesce(
|
||||||
// coalesce(
|
post_aggregates::comments.nullable() - post_actions::read_comments_amount.nullable(),
|
||||||
// post_aggregates::comments.nullable() - post_actions::read_comments_amount.nullable(),
|
post_aggregates::comments,
|
||||||
// post_aggregates::comments,
|
),
|
||||||
// )
|
post_actions::saved.nullable().is_not_null(),
|
||||||
// .nullable(),
|
post_actions::read.nullable().is_not_null(),
|
||||||
// post_actions::saved.nullable().is_not_null(),
|
post_actions::hidden.nullable().is_not_null(),
|
||||||
// post_actions::read.nullable().is_not_null(),
|
post_actions::like_score.nullable(),
|
||||||
// post_actions::hidden.nullable().is_not_null(),
|
image_details::all_columns.nullable(),
|
||||||
// post_actions::like_score.nullable(),
|
// Comment-specific
|
||||||
// // Comment-specific
|
comment::all_columns.nullable(),
|
||||||
// comment::all_columns.nullable(),
|
comment_aggregates::all_columns.nullable(),
|
||||||
// comment_aggregates::all_columns.nullable(),
|
comment_actions::saved.nullable().is_not_null(),
|
||||||
// comment_actions::saved.nullable().is_not_null(),
|
comment_actions::like_score.nullable(),
|
||||||
// comment_actions::like_score.nullable(),
|
// Shared
|
||||||
// // Private-message-specific
|
post::all_columns,
|
||||||
// private_message_profile::all_columns.nullable(),
|
community::all_columns,
|
||||||
// private_message::all_columns.nullable(),
|
person::all_columns,
|
||||||
// // Shared
|
CommunityFollower::select_subscribed_type(),
|
||||||
// person::all_columns,
|
local_user::admin.nullable().is_not_null(),
|
||||||
// aliases::person1.fields(person::all_columns),
|
creator_community_actions
|
||||||
// community::all_columns.nullable(),
|
.field(community_actions::became_moderator)
|
||||||
// CommunityFollower::select_subscribed_type(),
|
.nullable()
|
||||||
// aliases::person2.fields(person::all_columns.nullable()),
|
.is_not_null(),
|
||||||
// local_user::admin.nullable().is_not_null(),
|
creator_community_actions
|
||||||
// creator_community_actions
|
.field(community_actions::received_ban)
|
||||||
// .field(community_actions::received_ban)
|
.nullable()
|
||||||
// .nullable()
|
.is_not_null(),
|
||||||
// .is_not_null(),
|
person_actions::blocked.nullable().is_not_null(),
|
||||||
// creator_community_actions
|
community_actions::received_ban.nullable().is_not_null(),
|
||||||
// .field(community_actions::became_moderator)
|
|
||||||
// .nullable()
|
|
||||||
// .is_not_null(),
|
|
||||||
// person_actions::blocked.nullable().is_not_null(),
|
|
||||||
))
|
))
|
||||||
.into_boxed();
|
.into_boxed();
|
||||||
|
|
||||||
|
@ -210,9 +200,13 @@ impl ProfileCombinedQuery {
|
||||||
query = query.filter(community::id.eq(community_id));
|
query = query.filter(community::id.eq(community_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If its not an admin, get only the ones you mod
|
// If its saved only, then filter
|
||||||
if !user.local_user.admin {
|
if self.saved_only.unwrap_or_default() {
|
||||||
query = query.filter(community_actions::became_moderator.is_not_null());
|
query = query.filter(
|
||||||
|
comment_actions::saved
|
||||||
|
.is_not_null()
|
||||||
|
.or(post_actions::saved.is_not_null()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut query = PaginatedQueryBuilder::new(query);
|
let mut query = PaginatedQueryBuilder::new(query);
|
||||||
|
@ -225,25 +219,11 @@ impl ProfileCombinedQuery {
|
||||||
query = query.after(page_after);
|
query = query.after(page_after);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If viewing all profiles, order by newest, but if viewing unresolved only, show the oldest
|
// Sorting by published
|
||||||
// first (FIFO)
|
|
||||||
if self.unresolved_only.unwrap_or_default() {
|
|
||||||
query = query
|
query = query
|
||||||
.filter(
|
.then_desc(ReverseTimestampKey(key::published))
|
||||||
post_profile::resolved
|
|
||||||
.eq(false)
|
|
||||||
.or(comment_profile::resolved.eq(false))
|
|
||||||
.or(private_message_profile::resolved.eq(false)),
|
|
||||||
)
|
|
||||||
// TODO: when a `then_asc` method is added, use it here, make the id sort direction match,
|
|
||||||
// and remove the separate index; unless additional columns are added to this sort
|
|
||||||
.then_desc(ReverseTimestampKey(key::published));
|
|
||||||
} else {
|
|
||||||
query = query.then_desc(key::published);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tie breaker
|
// Tie breaker
|
||||||
query = query.then_desc(key::id);
|
.then_desc(key::id);
|
||||||
|
|
||||||
let res = query.load::<ProfileCombinedViewInternal>(conn).await?;
|
let res = query.load::<ProfileCombinedViewInternal>(conn).await?;
|
||||||
|
|
||||||
|
@ -259,14 +239,28 @@ fn map_to_enum(view: ProfileCombinedViewInternal) -> Option<ProfileCombinedView>
|
||||||
// Use for a short alias
|
// Use for a short alias
|
||||||
let v = view;
|
let v = view;
|
||||||
|
|
||||||
if let (Some(post), Some(community), Some(unread_comments), Some(counts)) =
|
if let (Some(comment), Some(counts)) = (v.comment, v.comment_counts) {
|
||||||
(v.post, v.community, v.post_unread_comments, v.post_counts)
|
Some(ProfileCombinedView::Comment(CommentView {
|
||||||
{
|
comment,
|
||||||
Some(ProfileCombinedView::Post(PostView {
|
|
||||||
post,
|
|
||||||
community,
|
|
||||||
unread_comments,
|
|
||||||
counts,
|
counts,
|
||||||
|
post: v.post,
|
||||||
|
community: v.community,
|
||||||
|
creator: v.item_creator,
|
||||||
|
creator_banned_from_community: v.item_creator_banned_from_community,
|
||||||
|
creator_is_moderator: v.item_creator_is_moderator,
|
||||||
|
creator_is_admin: v.item_creator_is_admin,
|
||||||
|
creator_blocked: v.item_creator_blocked,
|
||||||
|
subscribed: v.subscribed,
|
||||||
|
saved: v.comment_saved,
|
||||||
|
my_vote: v.my_comment_vote,
|
||||||
|
banned_from_community: v.banned_from_community,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Some(ProfileCombinedView::Post(PostView {
|
||||||
|
post: v.post,
|
||||||
|
community: v.community,
|
||||||
|
unread_comments: v.post_unread_comments,
|
||||||
|
counts: v.post_counts,
|
||||||
creator: v.item_creator,
|
creator: v.item_creator,
|
||||||
creator_banned_from_community: v.item_creator_banned_from_community,
|
creator_banned_from_community: v.item_creator_banned_from_community,
|
||||||
creator_is_moderator: v.item_creator_is_moderator,
|
creator_is_moderator: v.item_creator_is_moderator,
|
||||||
|
@ -277,28 +271,8 @@ fn map_to_enum(view: ProfileCombinedViewInternal) -> Option<ProfileCombinedView>
|
||||||
read: v.post_read,
|
read: v.post_read,
|
||||||
hidden: v.post_hidden,
|
hidden: v.post_hidden,
|
||||||
my_vote: v.my_post_vote,
|
my_vote: v.my_post_vote,
|
||||||
|
image_details: v.image_details,
|
||||||
|
banned_from_community: v.banned_from_community,
|
||||||
}))
|
}))
|
||||||
} else if let (Some(comment), Some(counts), Some(post), Some(community)) = (
|
|
||||||
v.comment,
|
|
||||||
v.comment_counts,
|
|
||||||
v.post.clone(),
|
|
||||||
v.community.clone(),
|
|
||||||
) {
|
|
||||||
Some(ProfileCombinedView::Comment(CommentView {
|
|
||||||
comment,
|
|
||||||
counts,
|
|
||||||
post,
|
|
||||||
community,
|
|
||||||
creator: v.item_creator,
|
|
||||||
creator_banned_from_community: v.item_creator_banned_from_community,
|
|
||||||
creator_is_moderator: v.item_creator_is_moderator,
|
|
||||||
creator_is_admin: v.item_creator_is_admin,
|
|
||||||
creator_blocked: v.item_creator_blocked,
|
|
||||||
subscribed: v.subscribed,
|
|
||||||
saved: v.comment_saved,
|
|
||||||
my_vote: v.my_comment_vote,
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,8 +310,8 @@ pub struct ProfileCombinedViewInternal {
|
||||||
pub my_post_vote: Option<i16>,
|
pub my_post_vote: Option<i16>,
|
||||||
pub image_details: Option<ImageDetails>,
|
pub image_details: Option<ImageDetails>,
|
||||||
// Comment-specific
|
// Comment-specific
|
||||||
pub comment: Comment,
|
pub comment: Option<Comment>,
|
||||||
pub comment_counts: CommentAggregates,
|
pub comment_counts: Option<CommentAggregates>,
|
||||||
pub comment_saved: bool,
|
pub comment_saved: bool,
|
||||||
pub my_comment_vote: Option<i16>,
|
pub my_comment_vote: Option<i16>,
|
||||||
// Shared
|
// Shared
|
||||||
|
@ -323,7 +323,6 @@ pub struct ProfileCombinedViewInternal {
|
||||||
pub item_creator_is_moderator: bool,
|
pub item_creator_is_moderator: bool,
|
||||||
pub item_creator_banned_from_community: bool,
|
pub item_creator_banned_from_community: bool,
|
||||||
pub item_creator_blocked: bool,
|
pub item_creator_blocked: bool,
|
||||||
pub item_saved: bool,
|
|
||||||
pub banned_from_community: bool,
|
pub banned_from_community: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
DROP TABLE profile_combined;
|
DROP TABLE profile_combined;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ CREATE TABLE profile_combined (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
published timestamptz NOT NULL,
|
published timestamptz NOT NULL,
|
||||||
post_id int UNIQUE REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
post_id int UNIQUE REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
comment_id int UNIQUE REFERENCES comment ON UPDATE CASCADE ON DELETE CASCADE,
|
comment_id int UNIQUE REFERENCES COMMENT ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
-- Make sure only one of the columns is not null
|
-- Make sure only one of the columns is not null
|
||||||
CHECK ((post_id IS NOT NULL)::integer + (comment_id IS NOT NULL)::integer = 1)
|
CHECK ((post_id IS NOT NULL)::integer + (comment_id IS NOT NULL)::integer = 1)
|
||||||
);
|
);
|
||||||
|
@ -27,3 +27,4 @@ SELECT
|
||||||
id
|
id
|
||||||
FROM
|
FROM
|
||||||
comment;
|
comment;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue