use crate::error::Result; use deadpool_postgres::GenericClient; pub mod actor; pub mod bulk_copy; pub mod bulk_resolve; pub mod composite_builders; pub mod gates; pub mod id_resolution; pub mod labels; pub mod operations; pub mod record_exists; pub mod workers; pub use actor::*; pub use gates::*; pub use labels::*; pub use operations::*; pub use record_exists::record_exists; /// Check if a recipient has muted a thread /// /// # Arguments /// /// * `recipient_actor_id` - The actor_id of the potential recipient /// * `root_post_actor_id` - The actor_id of the root post author /// * `root_post_rkey` - The rkey (as i64) of the root post /// /// # Returns /// /// `true` if the recipient has muted this thread, `false` otherwise pub async fn is_thread_muted( conn: &C, recipient_actor_id: i32, root_post_actor_id: i32, root_post_rkey: i64, ) -> Result { let row = conn .query_opt( "SELECT 1 FROM actors, unnest(COALESCE(thread_mutes, ARRAY[]::thread_mute_record[])) AS tm WHERE id = $1 AND (tm).root_post_actor_id = $2 AND (tm).root_post_rkey = $3", &[&recipient_actor_id, &root_post_actor_id, &root_post_rkey], ) .await?; Ok(row.is_some()) } /// Walk up the reply chain to get the parent post's author actor_id and parent URI /// /// This is used by NotifyReplyChain to traverse the reply chain and notify ancestors. /// Returns (author_actor_id, parent_uri) if the post exists, None if not found. pub async fn get_reply_chain_parent( conn: &C, post_uri: &str, ) -> Result)>> { let row_opt = conn .query_opt( "WITH post_parts AS ( SELECT SPLIT_PART(SUBSTRING($1 FROM 6), '/', 1) as did, SPLIT_PART(SUBSTRING($1 FROM 6), '/', 3) as rkey ), post_lookup AS ( SELECT p.actor_id, p.parent_post_actor_id, p.parent_post_rkey FROM post_parts pp INNER JOIN actors a ON a.did = pp.did INNER JOIN posts p ON p.actor_id = a.id AND p.rkey = tid_to_i64(pp.rkey) ) SELECT pl.actor_id, CASE WHEN pl.parent_post_actor_id IS NOT NULL THEN 'at://' || pa.did || '/app.bsky.feed.post/' || i64_to_tid(pl.parent_post_rkey) ELSE NULL END as parent_uri FROM post_lookup pl LEFT JOIN actors pa ON pa.id = pl.parent_post_actor_id", &[&post_uri], ) .await?; Ok(row_opt.map(|row| { let author_actor_id: i32 = row.get(0); let parent_uri: Option = row.get(1); (author_actor_id, parent_uri) })) } /// Check if a post exists /// /// # Arguments /// /// * `actor_id` - The actor_id of the post author /// * `rkey` - The rkey (as i64) of the post /// /// # Returns /// /// `true` if the post exists, `false` otherwise /// /// This is a simple lookup helper to consolidate the many inline EXISTS queries /// scattered throughout the codebase. pub async fn post_exists( conn: &C, actor_id: i32, rkey: i64, ) -> Result { let exists: bool = conn .query_one( "SELECT EXISTS(SELECT 1 FROM posts WHERE actor_id = $1 AND rkey = $2)", &[&actor_id, &rkey], ) .await? .get(0); Ok(exists) }