mirror of https://github.com/LemmyNet/lemmy.git
Remove left joins and use only one call to select method in post_view.rs (#3865)
* Use same joins for read and list in post_view.rs * fmt * rerun ci * rerun ci * Update post_view.rs * rerun ci * rerun ci * Update post_view.rs * Use `exists` * Update post_view.rs * Update post_view.rs * Update post_view.rs * rerun ci * Update post_view.rs * person_id_join parameter * rerun ci * fmt * Update post_view.rs * rerun ci * Update post_view.rs * rerun ci * fmt * Update post_view.rs * fmt * Use into_sql * Update post_view.rs * Use inferred query source for BoxableExpression * Update post_view.rs * Update post_view.rs * Update community.rs * Update community.rs * Update post_view.rs * fmt * Update community.rs * Update community.rs * Update community.rs * Update community.rs * Update community.rs * Update post_view.rs * Update community.rs * fmt * Update post_view.rs * Update post_view.rs * Update post_view.rs * Update post_view.rs * Update post_view.rs * Update post_view.rs * Update post_view.rs * fmt * Update post_view.rs * Update post_view.rs * fix * trigger ci --------- Co-authored-by: Dessalines <dessalines@users.noreply.github.com> Co-authored-by: phiresky <phireskyde+git@gmail.com>use_person_id_for_add_admin
parent
a57658d99c
commit
5b5ac0f37d
|
@ -1,15 +1,15 @@
|
||||||
use crate::structs::{LocalUserView, PostView};
|
use crate::structs::{LocalUserView, PostView};
|
||||||
use diesel::{
|
use diesel::{
|
||||||
debug_query,
|
debug_query,
|
||||||
dsl::IntervalDsl,
|
dsl::{exists, not, IntervalDsl},
|
||||||
pg::Pg,
|
pg::Pg,
|
||||||
result::Error,
|
result::Error,
|
||||||
sql_function,
|
sql_function,
|
||||||
sql_types::{self, Timestamptz},
|
sql_types::{self, Timestamptz},
|
||||||
BoolExpressionMethods,
|
BoolExpressionMethods,
|
||||||
|
BoxableExpression,
|
||||||
ExpressionMethods,
|
ExpressionMethods,
|
||||||
IntoSql,
|
IntoSql,
|
||||||
JoinOnDsl,
|
|
||||||
NullableExpressionMethods,
|
NullableExpressionMethods,
|
||||||
PgTextExpressionMethods,
|
PgTextExpressionMethods,
|
||||||
QueryDsl,
|
QueryDsl,
|
||||||
|
@ -33,7 +33,6 @@ use lemmy_db_schema::{
|
||||||
post_read,
|
post_read,
|
||||||
post_saved,
|
post_saved,
|
||||||
},
|
},
|
||||||
source::community::CommunityFollower,
|
|
||||||
utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
|
utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
|
||||||
ListingType,
|
ListingType,
|
||||||
SortType,
|
SortType,
|
||||||
|
@ -46,89 +45,145 @@ fn queries<'a>() -> Queries<
|
||||||
impl ReadFn<'a, PostView, (PostId, Option<PersonId>, bool)>,
|
impl ReadFn<'a, PostView, (PostId, Option<PersonId>, bool)>,
|
||||||
impl ListFn<'a, PostView, PostQuery<'a>>,
|
impl ListFn<'a, PostView, PostQuery<'a>>,
|
||||||
> {
|
> {
|
||||||
let all_joins = |query: post_aggregates::BoxedQuery<'a, Pg>, my_person_id: Option<PersonId>| {
|
let is_creator_banned_from_community = exists(
|
||||||
// The left join below will return None in this case
|
community_person_ban::table.filter(
|
||||||
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
post_aggregates::community_id
|
||||||
|
.eq(community_person_ban::community_id)
|
||||||
|
.and(community_person_ban::person_id.eq(post_aggregates::creator_id)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let is_saved = |person_id| {
|
||||||
|
exists(
|
||||||
|
post_saved::table.filter(
|
||||||
|
post_aggregates::post_id
|
||||||
|
.eq(post_saved::post_id)
|
||||||
|
.and(post_saved::person_id.eq(person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_read = |person_id| {
|
||||||
|
exists(
|
||||||
|
post_read::table.filter(
|
||||||
|
post_aggregates::post_id
|
||||||
|
.eq(post_read::post_id)
|
||||||
|
.and(post_read::person_id.eq(person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_creator_blocked = |person_id| {
|
||||||
|
exists(
|
||||||
|
person_block::table.filter(
|
||||||
|
post_aggregates::creator_id
|
||||||
|
.eq(person_block::target_id)
|
||||||
|
.and(person_block::person_id.eq(person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let score = |person_id| {
|
||||||
|
post_like::table
|
||||||
|
.filter(
|
||||||
|
post_aggregates::post_id
|
||||||
|
.eq(post_like::post_id)
|
||||||
|
.and(post_like::person_id.eq(person_id)),
|
||||||
|
)
|
||||||
|
.select(post_like::score.nullable())
|
||||||
|
.single_value()
|
||||||
|
};
|
||||||
|
|
||||||
|
let all_joins = move |query: post_aggregates::BoxedQuery<'a, Pg>,
|
||||||
|
my_person_id: Option<PersonId>,
|
||||||
|
saved_only: bool| {
|
||||||
|
let is_saved_selection: Box<dyn BoxableExpression<_, Pg, SqlType = sql_types::Bool>> =
|
||||||
|
if saved_only {
|
||||||
|
Box::new(true.into_sql::<sql_types::Bool>())
|
||||||
|
} else if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(is_saved(person_id))
|
||||||
|
} else {
|
||||||
|
Box::new(false.into_sql::<sql_types::Bool>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_read_selection: Box<dyn BoxableExpression<_, Pg, SqlType = sql_types::Bool>> =
|
||||||
|
if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(is_read(person_id))
|
||||||
|
} else {
|
||||||
|
Box::new(false.into_sql::<sql_types::Bool>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_creator_blocked_selection: Box<dyn BoxableExpression<_, Pg, SqlType = sql_types::Bool>> =
|
||||||
|
if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(is_creator_blocked(person_id))
|
||||||
|
} else {
|
||||||
|
Box::new(false.into_sql::<sql_types::Bool>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let subscribed_type_selection: Box<
|
||||||
|
dyn BoxableExpression<_, Pg, SqlType = sql_types::Nullable<sql_types::Bool>>,
|
||||||
|
> = if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(
|
||||||
|
community_follower::table
|
||||||
|
.filter(
|
||||||
|
post_aggregates::community_id
|
||||||
|
.eq(community_follower::community_id)
|
||||||
|
.and(community_follower::person_id.eq(person_id)),
|
||||||
|
)
|
||||||
|
.select(community_follower::pending.nullable())
|
||||||
|
.single_value(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Box::new(None::<bool>.into_sql::<sql_types::Nullable<sql_types::Bool>>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let score_selection: Box<
|
||||||
|
dyn BoxableExpression<_, Pg, SqlType = sql_types::Nullable<sql_types::SmallInt>>,
|
||||||
|
> = if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(score(person_id))
|
||||||
|
} else {
|
||||||
|
Box::new(None::<i16>.into_sql::<sql_types::Nullable<sql_types::SmallInt>>())
|
||||||
|
};
|
||||||
|
|
||||||
|
let read_comments: Box<
|
||||||
|
dyn BoxableExpression<_, Pg, SqlType = sql_types::Nullable<sql_types::BigInt>>,
|
||||||
|
> = if let Some(person_id) = my_person_id {
|
||||||
|
Box::new(
|
||||||
|
person_post_aggregates::table
|
||||||
|
.filter(
|
||||||
|
post_aggregates::post_id
|
||||||
|
.eq(person_post_aggregates::post_id)
|
||||||
|
.and(person_post_aggregates::person_id.eq(person_id)),
|
||||||
|
)
|
||||||
|
.select(person_post_aggregates::read_comments.nullable())
|
||||||
|
.single_value(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Box::new(None::<i64>.into_sql::<sql_types::Nullable<sql_types::BigInt>>())
|
||||||
|
};
|
||||||
|
|
||||||
query
|
query
|
||||||
.inner_join(person::table)
|
.inner_join(person::table)
|
||||||
.inner_join(community::table)
|
.inner_join(community::table)
|
||||||
.left_join(
|
|
||||||
community_person_ban::table.on(
|
|
||||||
post_aggregates::community_id
|
|
||||||
.eq(community_person_ban::community_id)
|
|
||||||
.and(community_person_ban::person_id.eq(post_aggregates::creator_id)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.inner_join(post::table)
|
.inner_join(post::table)
|
||||||
.left_join(
|
.select((
|
||||||
community_follower::table.on(
|
post::all_columns,
|
||||||
post_aggregates::community_id
|
person::all_columns,
|
||||||
.eq(community_follower::community_id)
|
community::all_columns,
|
||||||
.and(community_follower::person_id.eq(person_id_join)),
|
is_creator_banned_from_community,
|
||||||
|
post_aggregates::all_columns,
|
||||||
|
subscribed_type_selection,
|
||||||
|
is_saved_selection,
|
||||||
|
is_read_selection,
|
||||||
|
is_creator_blocked_selection,
|
||||||
|
score_selection,
|
||||||
|
coalesce(
|
||||||
|
post_aggregates::comments.nullable() - read_comments,
|
||||||
|
post_aggregates::comments,
|
||||||
),
|
),
|
||||||
)
|
))
|
||||||
.left_join(
|
|
||||||
community_moderator::table.on(
|
|
||||||
post::community_id
|
|
||||||
.eq(community_moderator::community_id)
|
|
||||||
.and(community_moderator::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
post_saved::table.on(
|
|
||||||
post_aggregates::post_id
|
|
||||||
.eq(post_saved::post_id)
|
|
||||||
.and(post_saved::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
post_read::table.on(
|
|
||||||
post_aggregates::post_id
|
|
||||||
.eq(post_read::post_id)
|
|
||||||
.and(post_read::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
person_block::table.on(
|
|
||||||
post_aggregates::creator_id
|
|
||||||
.eq(person_block::target_id)
|
|
||||||
.and(person_block::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
post_like::table.on(
|
|
||||||
post_aggregates::post_id
|
|
||||||
.eq(post_like::post_id)
|
|
||||||
.and(post_like::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
person_post_aggregates::table.on(
|
|
||||||
post_aggregates::post_id
|
|
||||||
.eq(person_post_aggregates::post_id)
|
|
||||||
.and(person_post_aggregates::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let selection = (
|
|
||||||
post::all_columns,
|
|
||||||
person::all_columns,
|
|
||||||
community::all_columns,
|
|
||||||
community_person_ban::id.nullable().is_not_null(),
|
|
||||||
post_aggregates::all_columns,
|
|
||||||
CommunityFollower::select_subscribed_type(),
|
|
||||||
post_saved::id.nullable().is_not_null(),
|
|
||||||
post_read::id.nullable().is_not_null(),
|
|
||||||
person_block::id.nullable().is_not_null(),
|
|
||||||
post_like::score.nullable(),
|
|
||||||
coalesce(
|
|
||||||
post_aggregates::comments.nullable() - person_post_aggregates::read_comments.nullable(),
|
|
||||||
post_aggregates::comments,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
let read =
|
let read =
|
||||||
move |mut conn: DbConn<'a>,
|
move |mut conn: DbConn<'a>,
|
||||||
(post_id, my_person_id, is_mod_or_admin): (PostId, Option<PersonId>, bool)| async move {
|
(post_id, my_person_id, is_mod_or_admin): (PostId, Option<PersonId>, bool)| async move {
|
||||||
|
@ -140,8 +195,8 @@ fn queries<'a>() -> Queries<
|
||||||
.filter(post_aggregates::post_id.eq(post_id))
|
.filter(post_aggregates::post_id.eq(post_id))
|
||||||
.into_boxed(),
|
.into_boxed(),
|
||||||
my_person_id,
|
my_person_id,
|
||||||
)
|
false,
|
||||||
.select(selection);
|
);
|
||||||
|
|
||||||
// Hide deleted and removed for non-admins or mods
|
// Hide deleted and removed for non-admins or mods
|
||||||
if !is_mod_or_admin {
|
if !is_mod_or_admin {
|
||||||
|
@ -172,22 +227,11 @@ fn queries<'a>() -> Queries<
|
||||||
let person_id_join = person_id.unwrap_or(PersonId(-1));
|
let person_id_join = person_id.unwrap_or(PersonId(-1));
|
||||||
let local_user_id_join = local_user_id.unwrap_or(LocalUserId(-1));
|
let local_user_id_join = local_user_id.unwrap_or(LocalUserId(-1));
|
||||||
|
|
||||||
let mut query = all_joins(post_aggregates::table.into_boxed(), person_id)
|
let mut query = all_joins(
|
||||||
.left_join(
|
post_aggregates::table.into_boxed(),
|
||||||
community_block::table.on(
|
person_id,
|
||||||
post_aggregates::community_id
|
options.saved_only,
|
||||||
.eq(community_block::community_id)
|
);
|
||||||
.and(community_block::person_id.eq(person_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.left_join(
|
|
||||||
local_user_language::table.on(
|
|
||||||
post::language_id
|
|
||||||
.eq(local_user_language::language_id)
|
|
||||||
.and(local_user_language::local_user_id.eq(local_user_id_join)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.select(selection);
|
|
||||||
|
|
||||||
let is_creator = options.creator_id == options.local_user.map(|l| l.person.id);
|
let is_creator = options.creator_id == options.local_user.map(|l| l.person.id);
|
||||||
// only show deleted posts to creator
|
// only show deleted posts to creator
|
||||||
|
@ -220,25 +264,30 @@ fn queries<'a>() -> Queries<
|
||||||
query = query.filter(post_aggregates::creator_id.eq(creator_id));
|
query = query.filter(post_aggregates::creator_id.eq(creator_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(listing_type) = options.listing_type {
|
if let (Some(listing_type), Some(person_id)) = (options.listing_type, person_id) {
|
||||||
|
let is_subscribed = exists(
|
||||||
|
community_follower::table.filter(
|
||||||
|
post_aggregates::community_id
|
||||||
|
.eq(community_follower::community_id)
|
||||||
|
.and(community_follower::person_id.eq(person_id)),
|
||||||
|
),
|
||||||
|
);
|
||||||
match listing_type {
|
match listing_type {
|
||||||
ListingType::Subscribed => query = query.filter(community_follower::pending.is_not_null()),
|
ListingType::Subscribed => query = query.filter(is_subscribed),
|
||||||
ListingType::Local => {
|
ListingType::Local => {
|
||||||
query = query.filter(community::local.eq(true)).filter(
|
query = query
|
||||||
community::hidden
|
.filter(community::local.eq(true))
|
||||||
.eq(false)
|
.filter(community::hidden.eq(false).or(is_subscribed));
|
||||||
.or(community_follower::person_id.eq(person_id_join)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ListingType::All => {
|
|
||||||
query = query.filter(
|
|
||||||
community::hidden
|
|
||||||
.eq(false)
|
|
||||||
.or(community_follower::person_id.eq(person_id_join)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
ListingType::All => query = query.filter(community::hidden.eq(false).or(is_subscribed)),
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query = query.filter(community_moderator::person_id.is_not_null());
|
query = query.filter(exists(
|
||||||
|
community_moderator::table.filter(
|
||||||
|
post::community_id
|
||||||
|
.eq(community_moderator::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(person_id)),
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,8 +323,8 @@ fn queries<'a>() -> Queries<
|
||||||
query = query.filter(person::bot_account.eq(false));
|
query = query.filter(person::bot_account.eq(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
if options.saved_only {
|
if let (true, Some(person_id)) = (options.saved_only, person_id) {
|
||||||
query = query.filter(post_saved::id.is_not_null());
|
query = query.filter(is_saved(person_id));
|
||||||
}
|
}
|
||||||
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
|
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
|
||||||
// setting wont be able to see saved posts.
|
// setting wont be able to see saved posts.
|
||||||
|
@ -285,27 +334,42 @@ fn queries<'a>() -> Queries<
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
{
|
{
|
||||||
// Do not hide read posts when it is a user profile view
|
// Do not hide read posts when it is a user profile view
|
||||||
if !options.is_profile_view {
|
if let (false, Some(person_id)) = (options.is_profile_view, person_id) {
|
||||||
query = query.filter(post_read::post_id.is_null());
|
query = query.filter(not(is_read(person_id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.liked_only {
|
if let Some(person_id) = person_id {
|
||||||
query = query.filter(post_like::score.eq(1));
|
if options.liked_only {
|
||||||
} else if options.disliked_only {
|
query = query.filter(score(person_id).eq(1));
|
||||||
query = query.filter(post_like::score.eq(-1));
|
} else if options.disliked_only {
|
||||||
}
|
query = query.filter(score(person_id).eq(-1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Dont filter blocks or missing languages for moderator view type
|
// Dont filter blocks or missing languages for moderator view type
|
||||||
if options.local_user.is_some()
|
if let (Some(person_id), false) = (
|
||||||
&& options.listing_type.unwrap_or_default() != ListingType::ModeratorView
|
person_id,
|
||||||
{
|
options.listing_type.unwrap_or_default() == ListingType::ModeratorView,
|
||||||
|
) {
|
||||||
// Filter out the rows with missing languages
|
// Filter out the rows with missing languages
|
||||||
query = query.filter(local_user_language::language_id.is_not_null());
|
query = query.filter(exists(
|
||||||
|
local_user_language::table.filter(
|
||||||
|
post::language_id
|
||||||
|
.eq(local_user_language::language_id)
|
||||||
|
.and(local_user_language::local_user_id.eq(local_user_id_join)),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
// Don't show blocked communities or persons
|
// Don't show blocked communities or persons
|
||||||
query = query.filter(community_block::person_id.is_null());
|
query = query.filter(not(exists(
|
||||||
query = query.filter(person_block::person_id.is_null());
|
community_block::table.filter(
|
||||||
|
post_aggregates::community_id
|
||||||
|
.eq(community_block::community_id)
|
||||||
|
.and(community_block::person_id.eq(person_id_join)),
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
query = query.filter(not(is_creator_blocked(person_id)));
|
||||||
}
|
}
|
||||||
let now = diesel::dsl::now.into_sql::<Timestamptz>();
|
let now = diesel::dsl::now.into_sql::<Timestamptz>();
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 713ceed9c7ef84deaa222e68361e670e0763cd83
|
Subproject commit 1c42c579460871de7b4ea18e58dc25543b80d289
|
Loading…
Reference in New Issue