Optimize database queries in can_view_post()
This commit is contained in:
parent
7d89f65b37
commit
0a2a145807
2 changed files with 37 additions and 13 deletions
|
@ -3,7 +3,8 @@ use uuid::Uuid;
|
|||
|
||||
use crate::errors::DatabaseError;
|
||||
use crate::models::reactions::queries::find_favourited_by_user;
|
||||
use crate::models::relationships::queries::get_relationship;
|
||||
use crate::models::relationships::queries::has_relationship;
|
||||
use crate::models::relationships::types::RelationshipType;
|
||||
use crate::models::users::types::User;
|
||||
use super::queries::{get_posts, find_reposted_by_user};
|
||||
use super::types::{Post, PostActions, Visibility};
|
||||
|
@ -65,41 +66,41 @@ pub async fn can_view_post(
|
|||
user: Option<&User>,
|
||||
post: &Post,
|
||||
) -> Result<bool, DatabaseError> {
|
||||
let is_mentioned = |user: &User| {
|
||||
post.mentions.iter().any(|profile| profile.id == user.profile.id)
|
||||
};
|
||||
let result = match post.visibility {
|
||||
Visibility::Public => true,
|
||||
Visibility::Direct => {
|
||||
if let Some(user) = user {
|
||||
// Returns true if user is mentioned
|
||||
post.mentions.iter()
|
||||
.any(|profile| profile.id == user.profile.id)
|
||||
is_mentioned(user)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
Visibility::Followers => {
|
||||
if let Some(user) = user {
|
||||
let relationship = get_relationship(
|
||||
let is_following = has_relationship(
|
||||
db_client,
|
||||
&post.author.id,
|
||||
&user.id,
|
||||
&post.author.id,
|
||||
RelationshipType::Follow,
|
||||
).await?;
|
||||
let is_mentioned = post.mentions.iter()
|
||||
.any(|profile| profile.id == user.profile.id);
|
||||
relationship.followed_by || is_mentioned
|
||||
is_following || is_mentioned(user)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
Visibility::Subscribers => {
|
||||
if let Some(user) = user {
|
||||
let relationship = get_relationship(
|
||||
let is_subscriber = has_relationship(
|
||||
db_client,
|
||||
&post.author.id,
|
||||
&user.id,
|
||||
&post.author.id,
|
||||
RelationshipType::Subscription,
|
||||
).await?;
|
||||
let is_mentioned = post.mentions.iter()
|
||||
.any(|profile| profile.id == user.profile.id);
|
||||
relationship.subscription_from || is_mentioned
|
||||
is_subscriber || is_mentioned(user)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -87,6 +87,29 @@ pub async fn get_relationship(
|
|||
Ok(relationship_map)
|
||||
}
|
||||
|
||||
pub async fn has_relationship(
|
||||
db_client: &impl GenericClient,
|
||||
source_id: &Uuid,
|
||||
target_id: &Uuid,
|
||||
relationship_type: RelationshipType,
|
||||
) -> Result<bool, DatabaseError> {
|
||||
let maybe_row = db_client.query_opt(
|
||||
"
|
||||
SELECT 1
|
||||
FROM relationship
|
||||
WHERE
|
||||
source_id = $1 AND target_id = $2
|
||||
AND relationship_type = $3
|
||||
",
|
||||
&[
|
||||
&source_id,
|
||||
&target_id,
|
||||
&relationship_type,
|
||||
],
|
||||
).await?;
|
||||
Ok(maybe_row.is_some())
|
||||
}
|
||||
|
||||
pub async fn follow(
|
||||
db_client: &mut impl GenericClient,
|
||||
source_id: &Uuid,
|
||||
|
|
Loading…
Reference in a new issue