Avoid repeating attachment subquery in post queries

This commit is contained in:
silverpill 2021-11-11 18:35:27 +00:00
parent fa7bff4b31
commit 06010e4403
2 changed files with 45 additions and 34 deletions

View file

@ -5,6 +5,7 @@ use uuid::Uuid;
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::models::posts::helpers::get_actions_for_posts; use crate::models::posts::helpers::get_actions_for_posts;
use crate::models::posts::queries::RELATED_ATTACHMENTS;
use super::types::{EventType, Notification}; use super::types::{EventType, Notification};
async fn create_notification( async fn create_notification(
@ -68,14 +69,11 @@ pub async fn get_notifications(
db_client: &impl GenericClient, db_client: &impl GenericClient,
recipient_id: &Uuid, recipient_id: &Uuid,
) -> Result<Vec<Notification>, DatabaseError> { ) -> Result<Vec<Notification>, DatabaseError> {
let rows = db_client.query( let statement = format!(
" "
SELECT SELECT
notification, sender, post, post_author, notification, sender, post, post_author,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM notification FROM notification
JOIN actor_profile AS sender JOIN actor_profile AS sender
ON notification.sender_id = sender.id ON notification.sender_id = sender.id
@ -86,6 +84,10 @@ pub async fn get_notifications(
WHERE recipient_id = $1 WHERE recipient_id = $1
ORDER BY notification.created_at DESC ORDER BY notification.created_at DESC
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let rows = db_client.query(
statement.as_str(),
&[&recipient_id], &[&recipient_id],
).await?; ).await?;
let mut notifications: Vec<Notification> = rows.iter() let mut notifications: Vec<Notification> = rows.iter()

View file

@ -15,20 +15,23 @@ use crate::models::notifications::queries::create_reply_notification;
use crate::models::profiles::queries::update_post_count; use crate::models::profiles::queries::update_post_count;
use super::types::{DbPost, Post, PostCreateData}; use super::types::{DbPost, Post, PostCreateData};
pub const RELATED_ATTACHMENTS: &str =
"ARRAY(
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments";
pub async fn get_home_timeline( pub async fn get_home_timeline(
db_client: &impl GenericClient, db_client: &impl GenericClient,
current_user_id: &Uuid, current_user_id: &Uuid,
) -> Result<Vec<Post>, DatabaseError> { ) -> Result<Vec<Post>, DatabaseError> {
// Select posts from follows + own posts. // Select posts from follows + own posts.
// Do not select replies // Do not select replies
let rows = db_client.query( let statement = format!(
" "
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE WHERE
@ -42,6 +45,10 @@ pub async fn get_home_timeline(
) )
ORDER BY post.created_at DESC ORDER BY post.created_at DESC
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let rows = db_client.query(
statement.as_str(),
&[&current_user_id], &[&current_user_id],
).await?; ).await?;
let posts: Vec<Post> = rows.iter() let posts: Vec<Post> = rows.iter()
@ -64,15 +71,13 @@ pub async fn get_posts_by_author(
" "
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE {condition} WHERE {condition}
ORDER BY post.created_at DESC ORDER BY post.created_at DESC
", ",
related_attachments=RELATED_ATTACHMENTS,
condition=condition, condition=condition,
); );
let rows = db_client.query( let rows = db_client.query(
@ -155,18 +160,19 @@ pub async fn get_post_by_id(
db_client: &impl GenericClient, db_client: &impl GenericClient,
post_id: &Uuid, post_id: &Uuid,
) -> Result<Post, DatabaseError> { ) -> Result<Post, DatabaseError> {
let maybe_row = db_client.query_opt( let statement = format!(
" "
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE post.id = $1 WHERE post.id = $1
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let maybe_row = db_client.query_opt(
statement.as_str(),
&[&post_id], &[&post_id],
).await?; ).await?;
let post = match maybe_row { let post = match maybe_row {
@ -183,7 +189,7 @@ pub async fn get_thread(
post_id: &Uuid, post_id: &Uuid,
) -> Result<Vec<Post>, DatabaseError> { ) -> Result<Vec<Post>, DatabaseError> {
// TODO: limit recursion depth // TODO: limit recursion depth
let rows = db_client.query( let statement = format!(
" "
WITH RECURSIVE WITH RECURSIVE
ancestors (id, in_reply_to_id) AS ( ancestors (id, in_reply_to_id) AS (
@ -202,15 +208,16 @@ pub async fn get_thread(
) )
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN context ON post.id = context.id JOIN context ON post.id = context.id
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
ORDER BY context.path ORDER BY context.path
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let rows = db_client.query(
statement.as_str(),
&[&post_id], &[&post_id],
).await?; ).await?;
let posts: Vec<Post> = rows.iter() let posts: Vec<Post> = rows.iter()
@ -226,18 +233,19 @@ pub async fn get_post_by_object_id(
db_client: &impl GenericClient, db_client: &impl GenericClient,
object_id: &str, object_id: &str,
) -> Result<Post, DatabaseError> { ) -> Result<Post, DatabaseError> {
let maybe_row = db_client.query_opt( let statement = format!(
" "
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE post.object_id = $1 WHERE post.object_id = $1
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let maybe_row = db_client.query_opt(
statement.as_str(),
&[&object_id], &[&object_id],
).await?; ).await?;
let row = maybe_row.ok_or(DatabaseError::NotFound("post"))?; let row = maybe_row.ok_or(DatabaseError::NotFound("post"))?;
@ -249,18 +257,19 @@ pub async fn get_post_by_ipfs_cid(
db_client: &impl GenericClient, db_client: &impl GenericClient,
ipfs_cid: &str, ipfs_cid: &str,
) -> Result<Post, DatabaseError> { ) -> Result<Post, DatabaseError> {
let result = db_client.query_opt( let statement = format!(
" "
SELECT SELECT
post, actor_profile, post, actor_profile,
ARRAY( {related_attachments}
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM post FROM post
JOIN actor_profile ON post.author_id = actor_profile.id JOIN actor_profile ON post.author_id = actor_profile.id
WHERE post.ipfs_cid = $1 WHERE post.ipfs_cid = $1
", ",
related_attachments=RELATED_ATTACHMENTS,
);
let result = db_client.query_opt(
statement.as_str(),
&[&ipfs_cid], &[&ipfs_cid],
).await?; ).await?;
let post = match result { let post = match result {