Avoid repeating attachment subquery in post queries
This commit is contained in:
parent
fa7bff4b31
commit
06010e4403
2 changed files with 45 additions and 34 deletions
|
@ -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()
|
||||||
|
|
|
@ -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(),
|
||||||
&[¤t_user_id],
|
&[¤t_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 {
|
||||||
|
|
Loading…
Reference in a new issue