From 0a2a145807668010225c3b1943246ad5683e9d2a Mon Sep 17 00:00:00 2001 From: silverpill Date: Tue, 8 Feb 2022 18:25:48 +0000 Subject: [PATCH] Optimize database queries in can_view_post() --- src/models/posts/helpers.rs | 27 ++++++++++++++------------- src/models/relationships/queries.rs | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/models/posts/helpers.rs b/src/models/posts/helpers.rs index b8158d6..ec25a02 100644 --- a/src/models/posts/helpers.rs +++ b/src/models/posts/helpers.rs @@ -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 { + 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 } diff --git a/src/models/relationships/queries.rs b/src/models/relationships/queries.rs index 17df3ec..64b17bf 100644 --- a/src/models/relationships/queries.rs +++ b/src/models/relationships/queries.rs @@ -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 { + 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,