X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_schema%2Fsrc%2Ftraits.rs;h=cb128339b19f16adc33b001f7f0fb1f7f325c5f1;hb=f7f6766650b9b573a72075e564aed353c0131cd7;hp=aea36ed87a523f438620bdf7691d55c01e46b25e;hpb=9e0fa99c695df5d1c5e615d6f5de2b9d4bc91205;p=lemmy.git diff --git a/crates/db_schema/src/traits.rs b/crates/db_schema/src/traits.rs index aea36ed8..cb128339 100644 --- a/crates/db_schema/src/traits.rs +++ b/crates/db_schema/src/traits.rs @@ -1,62 +1,105 @@ -use crate::newtypes::{CommunityId, PersonId}; -use diesel::{result::Error, PgConnection}; +use crate::{ + newtypes::{CommunityId, DbUrl, PersonId}, + utils::{get_conn, DbPool}, +}; +use diesel::{ + associations::HasTable, + dsl, + query_builder::{DeleteStatement, IntoUpdateTarget}, + query_dsl::methods::{FindDsl, LimitDsl}, + result::Error, + Table, +}; +use diesel_async::{ + methods::{ExecuteDsl, LoadQuery}, + AsyncPgConnection, + RunQueryDsl, +}; + +/// Returned by `diesel::delete` +pub type Delete = DeleteStatement<::Table, ::WhereClause>; + +/// Returned by `Self::table().find(id)` +pub type Find = dsl::Find<::Table, ::IdType>; + +pub type PrimaryKey = <::Table as Table>::PrimaryKey; + +// Trying to create default implementations for `create` and `update` results in a lifetime mess and weird compile errors. +// https://github.com/rust-lang/rust/issues/102211 +#[async_trait] +pub trait Crud: HasTable + Sized +where + Self::Table: FindDsl, + Find: LimitDsl + IntoUpdateTarget + Send, + Delete>: ExecuteDsl + Send + 'static, + + // Used by `RunQueryDsl::first` + dsl::Limit>: LoadQuery<'static, AsyncPgConnection, Self> + Send + 'static, +{ + type InsertForm; + type UpdateForm; + type IdType: Send; + + async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result; + + async fn read(pool: &mut DbPool<'_>, id: Self::IdType) -> Result { + let query: Find = Self::table().find(id); + let conn = &mut *get_conn(pool).await?; + query.first::(conn).await + } -pub trait Crud { - type Form; - type IdType; - fn create(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn read(conn: &PgConnection, id: Self::IdType) -> Result - where - Self: Sized; - fn update(conn: &PgConnection, id: Self::IdType, form: &Self::Form) -> Result - where - Self: Sized; - fn delete(_conn: &PgConnection, _id: Self::IdType) -> Result - where - Self: Sized, - { - unimplemented!() + /// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column. + async fn update( + pool: &mut DbPool<'_>, + id: Self::IdType, + form: &Self::UpdateForm, + ) -> Result; + + async fn delete(pool: &mut DbPool<'_>, id: Self::IdType) -> Result { + let query: Delete> = diesel::delete(Self::table().find(id)); + let conn = &mut *get_conn(pool).await?; + query.execute(conn).await } } +#[async_trait] pub trait Followable { type Form; - fn follow(conn: &PgConnection, form: &Self::Form) -> Result + async fn follow(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn follow_accepted( - conn: &PgConnection, + async fn follow_accepted( + pool: &mut DbPool<'_>, community_id: CommunityId, person_id: PersonId, ) -> Result where Self: Sized; - fn unfollow(conn: &PgConnection, form: &Self::Form) -> Result + async fn unfollow(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn has_local_followers(conn: &PgConnection, community_id: CommunityId) -> Result; } +#[async_trait] pub trait Joinable { type Form; - fn join(conn: &PgConnection, form: &Self::Form) -> Result + async fn join(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn leave(conn: &PgConnection, form: &Self::Form) -> Result + async fn leave(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Likeable { type Form; type IdType; - fn like(conn: &PgConnection, form: &Self::Form) -> Result + async fn like(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn remove( - conn: &PgConnection, + async fn remove( + pool: &mut DbPool<'_>, person_id: PersonId, item_id: Self::IdType, ) -> Result @@ -64,61 +107,74 @@ pub trait Likeable { Self: Sized; } +#[async_trait] pub trait Bannable { type Form; - fn ban(conn: &PgConnection, form: &Self::Form) -> Result + async fn ban(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn unban(conn: &PgConnection, form: &Self::Form) -> Result + async fn unban(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Saveable { type Form; - fn save(conn: &PgConnection, form: &Self::Form) -> Result + async fn save(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn unsave(conn: &PgConnection, form: &Self::Form) -> Result + async fn unsave(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Blockable { type Form; - fn block(conn: &PgConnection, form: &Self::Form) -> Result + async fn block(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn unblock(conn: &PgConnection, form: &Self::Form) -> Result + async fn unblock(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Readable { type Form; - fn mark_as_read(conn: &PgConnection, form: &Self::Form) -> Result + async fn mark_as_read(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn mark_as_unread(conn: &PgConnection, form: &Self::Form) -> Result + async fn mark_as_unread(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Reportable { type Form; type IdType; - fn report(conn: &PgConnection, form: &Self::Form) -> Result + type ObjectIdType; + async fn report(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where Self: Sized; - fn resolve( - conn: &PgConnection, + async fn resolve( + pool: &mut DbPool<'_>, report_id: Self::IdType, resolver_id: PersonId, ) -> Result where Self: Sized; - fn unresolve( - conn: &PgConnection, + async fn resolve_all_for_object( + pool: &mut DbPool<'_>, + comment_id_: Self::ObjectIdType, + by_resolver_id: PersonId, + ) -> Result + where + Self: Sized; + async fn unresolve( + pool: &mut DbPool<'_>, report_id: Self::IdType, resolver_id: PersonId, ) -> Result @@ -126,39 +182,35 @@ pub trait Reportable { Self: Sized; } -pub trait DeleteableOrRemoveable { - fn blank_out_deleted_or_removed_info(self) -> Self; -} - -pub trait MaybeOptional { - fn get_optional(self) -> Option; -} - -impl MaybeOptional for T { - fn get_optional(self) -> Option { - Some(self) - } -} - -impl MaybeOptional for Option { - fn get_optional(self) -> Option { - self - } -} - -pub trait ToSafe { - type SafeColumns; - fn safe_columns_tuple() -> Self::SafeColumns; -} - -pub trait ToSafeSettings { - type SafeSettingsColumns; - fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns; +pub trait JoinView { + type JoinTuple; + fn from_tuple(tuple: Self::JoinTuple) -> Self + where + Self: Sized; } -pub trait ViewToVec { - type DbTuple; - fn from_tuple_to_vec(tuple: Vec) -> Vec +#[async_trait] +pub trait ApubActor { + async fn read_from_apub_id( + pool: &mut DbPool<'_>, + object_id: &DbUrl, + ) -> Result, Error> + where + Self: Sized; + /// - actor_name is the name of the community or user to read. + /// - include_deleted, if true, will return communities or users that were deleted/removed + async fn read_from_name( + pool: &mut DbPool<'_>, + actor_name: &str, + include_deleted: bool, + ) -> Result + where + Self: Sized; + async fn read_from_name_and_domain( + pool: &mut DbPool<'_>, + actor_name: &str, + protocol_domain: &str, + ) -> Result where Self: Sized; }