mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-29 07:41:20 +00:00
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 crate::structs::CommunityModeratorView;
|
||||||
use diesel::{result::Error, ExpressionMethods, QueryDsl};
|
use diesel::{dsl::exists, result::Error, select, ExpressionMethods, QueryDsl};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{CommunityId, PersonId},
|
newtypes::{CommunityId, PersonId},
|
||||||
|
@ -12,6 +12,25 @@ use lemmy_db_schema::{
|
||||||
type CommunityModeratorViewTuple = (Community, Person);
|
type CommunityModeratorViewTuple = (Community, Person);
|
||||||
|
|
||||||
impl CommunityModeratorView {
|
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> {
|
pub async fn for_community(pool: &DbPool, community_id: CommunityId) -> Result<Vec<Self>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
let res = community_moderator::table
|
let res = community_moderator::table
|
||||||
|
|
|
@ -90,29 +90,13 @@ impl CommunityView {
|
||||||
person_id: PersonId,
|
person_id: PersonId,
|
||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let is_mod = CommunityModeratorView::for_community(pool, community_id)
|
let is_mod =
|
||||||
.await
|
CommunityModeratorView::is_community_moderator(pool, community_id, person_id).await?;
|
||||||
.map(|v| {
|
|
||||||
v.into_iter()
|
|
||||||
.map(|m| m.moderator.id)
|
|
||||||
.collect::<Vec<PersonId>>()
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
.contains(&person_id);
|
|
||||||
if is_mod {
|
if is_mod {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_admin = PersonView::admins(pool)
|
PersonView::is_admin(pool, person_id).await
|
||||||
.await
|
|
||||||
.map(|v| {
|
|
||||||
v.into_iter()
|
|
||||||
.map(|a| a.person.id)
|
|
||||||
.collect::<Vec<PersonId>>()
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
.contains(&person_id);
|
|
||||||
Ok(is_admin)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ use diesel_async::RunQueryDsl;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::PersonAggregates,
|
aggregates::structs::PersonAggregates,
|
||||||
newtypes::PersonId,
|
newtypes::PersonId,
|
||||||
|
schema,
|
||||||
schema::{person, person_aggregates},
|
schema::{person, person_aggregates},
|
||||||
source::person::Person,
|
source::person::Person,
|
||||||
traits::JoinView,
|
traits::JoinView,
|
||||||
|
@ -34,6 +35,16 @@ impl PersonView {
|
||||||
Ok(Self::from_tuple(res))
|
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> {
|
pub async fn admins(pool: &DbPool) -> Result<Vec<Self>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
let admins = person::table
|
let admins = person::table
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- Create an admin person index
|
-- 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
|
-- Compound indexes, using featured_, then the other sorts, proved to be much faster
|
||||||
-- Drop the old indexes
|
-- 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