improve admin and mod check to not do seq scans and return unnecessary data (#3483)
* improve admin and mod check * fix clippy * move admin index to existing code * Revert "move admin index to existing code" This reverts commit d0c58d5f4021e1775d0c1d30d8df6c7df87557c4. * third attempt at the migration * fix formatting * rebuild --------- Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
00f9f79a44
commit
922ee6a230
6 changed files with 39 additions and 21 deletions
|
@ -1,5 +1,5 @@
|
|||
use crate::structs::CommunityModeratorView;
|
||||
use diesel::{result::Error, ExpressionMethods, QueryDsl};
|
||||
use diesel::{dsl::exists, result::Error, select, ExpressionMethods, QueryDsl};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommunityId, PersonId},
|
||||
|
@ -12,6 +12,25 @@ use lemmy_db_schema::{
|
|||
type CommunityModeratorViewTuple = (Community, Person);
|
||||
|
||||
impl CommunityModeratorView {
|
||||
pub async fn is_community_moderator(
|
||||
pool: &DbPool,
|
||||
find_community_id: CommunityId,
|
||||
find_person_id: PersonId,
|
||||
) -> Result<bool, Error> {
|
||||
use lemmy_db_schema::schema::community_moderator::dsl::{
|
||||
community_id,
|
||||
community_moderator,
|
||||
person_id,
|
||||
};
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
community_moderator
|
||||
.filter(community_id.eq(find_community_id))
|
||||
.filter(person_id.eq(find_person_id)),
|
||||
))
|
||||
.get_result::<bool>(conn)
|
||||
.await
|
||||
}
|
||||
pub async fn for_community(pool: &DbPool, community_id: CommunityId) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let res = community_moderator::table
|
||||
|
|
|
@ -90,29 +90,13 @@ impl CommunityView {
|
|||
person_id: PersonId,
|
||||
community_id: CommunityId,
|
||||
) -> Result<bool, Error> {
|
||||
let is_mod = CommunityModeratorView::for_community(pool, community_id)
|
||||
.await
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
.map(|m| m.moderator.id)
|
||||
.collect::<Vec<PersonId>>()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.contains(&person_id);
|
||||
let is_mod =
|
||||
CommunityModeratorView::is_community_moderator(pool, community_id, person_id).await?;
|
||||
if is_mod {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let is_admin = PersonView::admins(pool)
|
||||
.await
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
.map(|a| a.person.id)
|
||||
.collect::<Vec<PersonId>>()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.contains(&person_id);
|
||||
Ok(is_admin)
|
||||
PersonView::is_admin(pool, person_id).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use diesel_async::RunQueryDsl;
|
|||
use lemmy_db_schema::{
|
||||
aggregates::structs::PersonAggregates,
|
||||
newtypes::PersonId,
|
||||
schema,
|
||||
schema::{person, person_aggregates},
|
||||
source::person::Person,
|
||||
traits::JoinView,
|
||||
|
@ -34,6 +35,16 @@ impl PersonView {
|
|||
Ok(Self::from_tuple(res))
|
||||
}
|
||||
|
||||
pub async fn is_admin(pool: &DbPool, person_id: PersonId) -> Result<bool, Error> {
|
||||
use schema::person::dsl::{admin, id, person};
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let is_admin = person
|
||||
.filter(id.eq(person_id))
|
||||
.select(admin)
|
||||
.first::<bool>(conn)
|
||||
.await?;
|
||||
Ok(is_admin)
|
||||
}
|
||||
pub async fn admins(pool: &DbPool) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let admins = person::table
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-- Create an admin person index
|
||||
create index idx_person_admin on person (admin);
|
||||
create index if not exists idx_person_admin on person (admin);
|
||||
|
||||
-- Compound indexes, using featured_, then the other sorts, proved to be much faster
|
||||
-- Drop the old indexes
|
||||
|
|
2
migrations/2023-07-05-000058_person-admin/down.sql
Normal file
2
migrations/2023-07-05-000058_person-admin/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
drop index idx_person_admin;
|
||||
create index idx_person_admin on person(admin);
|
2
migrations/2023-07-05-000058_person-admin/up.sql
Normal file
2
migrations/2023-07-05-000058_person-admin/up.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
drop index if exists idx_person_admin;
|
||||
create index idx_person_admin on person(admin) where admin; -- allow quickly finding all admins (PersonView::admins)
|
Loading…
Reference in a new issue