2022-05-03 17:44:13 +00:00
use crate ::structs ::CommunityFollowerView ;
2023-09-09 16:25:03 +00:00
use chrono ::Utc ;
2023-07-05 15:50:26 +00:00
use diesel ::{
dsl ::{ count_star , not } ,
result ::Error ,
ExpressionMethods ,
QueryDsl ,
} ;
2022-11-09 10:05:00 +00:00
use diesel_async ::RunQueryDsl ;
2020-12-18 18:38:32 +00:00
use lemmy_db_schema ::{
2023-09-09 16:25:03 +00:00
newtypes ::{ CommunityId , DbUrl , InstanceId , PersonId } ,
2021-03-10 22:33:55 +00:00
schema ::{ community , community_follower , person } ,
2023-09-09 16:25:03 +00:00
utils ::{ functions ::coalesce , get_conn , DbPool } ,
2020-12-18 18:38:32 +00:00
} ;
2020-12-06 04:37:16 +00:00
impl CommunityFollowerView {
2023-09-09 16:25:03 +00:00
/// return a list of local community ids and remote inboxes that at least one user of the given instance has followed
pub async fn get_instance_followed_community_inboxes (
pool : & mut DbPool < '_ > ,
instance_id : InstanceId ,
published_since : chrono ::DateTime < Utc > ,
) -> Result < Vec < ( CommunityId , DbUrl ) > , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
// In most cases this will fetch the same url many times (the shared inbox url)
// PG will only send a single copy to rust, but it has to scan through all follower rows (same as it was before).
// So on the PG side it would be possible to optimize this further by adding e.g. a new table community_followed_instances (community_id, instance_id)
// that would work for all instances that support fully shared inboxes.
// It would be a bit more complicated though to keep it in sync.
community_follower ::table
. inner_join ( community ::table )
. inner_join ( person ::table )
. filter ( person ::instance_id . eq ( instance_id ) )
. filter ( community ::local ) // this should be a no-op since community_followers table only has local-person+remote-community or remote-person+local-community
. filter ( not ( person ::local ) )
. filter ( community_follower ::published . gt ( published_since . naive_utc ( ) ) )
. select ( (
community ::id ,
coalesce ( person ::shared_inbox_url , person ::inbox_url ) ,
) )
. distinct ( ) // only need each community_id, inbox combination once
. load ::< ( CommunityId , DbUrl ) > ( conn )
. await
}
2023-07-05 15:50:26 +00:00
pub async fn get_community_follower_inboxes (
2023-07-11 13:09:59 +00:00
pool : & mut DbPool < '_ > ,
2023-07-05 15:50:26 +00:00
community_id : CommunityId ,
) -> Result < Vec < DbUrl > , Error > {
2022-11-09 10:05:00 +00:00
let conn = & mut get_conn ( pool ) . await ? ;
2020-12-06 04:37:16 +00:00
let res = community_follower ::table
2023-07-05 15:50:26 +00:00
. filter ( community_follower ::community_id . eq ( community_id ) )
. filter ( not ( person ::local ) )
2021-03-10 22:33:55 +00:00
. inner_join ( person ::table )
2023-07-05 15:50:26 +00:00
. select ( coalesce ( person ::shared_inbox_url , person ::inbox_url ) )
. distinct ( )
. load ::< DbUrl > ( conn )
. await ? ;
Ok ( res )
}
pub async fn count_community_followers (
2023-07-11 13:09:59 +00:00
pool : & mut DbPool < '_ > ,
2023-07-05 15:50:26 +00:00
community_id : CommunityId ,
) -> Result < i64 , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
let res = community_follower ::table
2020-12-16 18:59:43 +00:00
. filter ( community_follower ::community_id . eq ( community_id ) )
2023-07-05 15:50:26 +00:00
. select ( count_star ( ) )
. first ::< i64 > ( conn )
2022-11-09 10:05:00 +00:00
. await ? ;
2020-12-06 04:37:16 +00:00
2023-07-05 15:50:26 +00:00
Ok ( res )
2020-12-06 04:37:16 +00:00
}
2023-07-11 13:09:59 +00:00
pub async fn for_person ( pool : & mut DbPool < '_ > , person_id : PersonId ) -> Result < Vec < Self > , Error > {
2022-11-09 10:05:00 +00:00
let conn = & mut get_conn ( pool ) . await ? ;
2023-08-31 13:26:10 +00:00
community_follower ::table
2020-12-06 04:37:16 +00:00
. inner_join ( community ::table )
2021-03-10 22:33:55 +00:00
. inner_join ( person ::table )
2023-03-01 17:19:46 +00:00
. select ( ( community ::all_columns , person ::all_columns ) )
2021-03-10 22:33:55 +00:00
. filter ( community_follower ::person_id . eq ( person_id ) )
2022-09-28 20:54:32 +00:00
. filter ( community ::deleted . eq ( false ) )
. filter ( community ::removed . eq ( false ) )
2022-02-01 20:00:54 +00:00
. order_by ( community ::title )
2023-08-31 13:26:10 +00:00
. load ::< CommunityFollowerView > ( conn )
. await
2020-12-11 01:39:42 +00:00
}
2020-12-06 04:37:16 +00:00
}