2 diesel::dsl::IntervalDsl,
4 schema::{federation_allowlist, federation_blocklist, instance},
5 source::instance::{Instance, InstanceForm},
6 utils::{get_conn, naive_now, DbPool},
9 dsl::{insert_into, now},
11 sql_types::{Nullable, Timestamp},
15 use diesel_async::RunQueryDsl;
18 /// Attempt to read Instance column for the given domain. If it doesnt exist, insert a new one.
19 /// There is no need for update as the domain of an existing instance cant change.
20 pub async fn read_or_create(pool: &mut DbPool<'_>, domain_: String) -> Result<Self, Error> {
21 use crate::schema::instance::domain;
22 let conn = &mut get_conn(pool).await?;
24 // First try to read the instance row and return directly if found
25 let instance = instance::table
26 .filter(domain.eq(&domain_))
31 Err(diesel::NotFound) => {
32 // Instance not in database yet, insert it
33 let form = InstanceForm::builder()
35 .updated(Some(naive_now()))
37 insert_into(instance::table)
39 // Necessary because this method may be called concurrently for the same domain. This
40 // could be handled with a transaction, but nested transactions arent allowed
41 .on_conflict(instance::domain)
44 .get_result::<Self>(conn)
50 pub async fn delete(pool: &mut DbPool<'_>, instance_id: InstanceId) -> Result<usize, Error> {
51 let conn = &mut get_conn(pool).await?;
52 diesel::delete(instance::table.find(instance_id))
57 pub async fn read_all(pool: &mut DbPool<'_>) -> Result<Vec<Instance>, Error> {
58 let conn = &mut get_conn(pool).await?;
60 .select(instance::all_columns)
65 pub async fn dead_instances(pool: &mut DbPool<'_>) -> Result<Vec<String>, Error> {
66 let conn = &mut get_conn(pool).await?;
68 .select(instance::domain)
69 .filter(coalesce(instance::updated, instance::published).lt(now - 3.days()))
75 pub async fn delete_all(pool: &mut DbPool<'_>) -> Result<usize, Error> {
76 let conn = &mut get_conn(pool).await?;
77 diesel::delete(instance::table).execute(conn).await
79 pub async fn allowlist(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
80 let conn = &mut get_conn(pool).await?;
82 .inner_join(federation_allowlist::table)
83 .select(instance::all_columns)
88 pub async fn blocklist(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
89 let conn = &mut get_conn(pool).await?;
91 .inner_join(federation_blocklist::table)
92 .select(instance::all_columns)
97 pub async fn linked(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
98 let conn = &mut get_conn(pool).await?;
100 .left_join(federation_blocklist::table)
101 .filter(federation_blocklist::id.is_null())
102 .select(instance::all_columns)
108 sql_function! { fn coalesce(x: Nullable<Timestamp>, y: Timestamp) -> Timestamp; }