diff --git a/crates/db_schema/src/traits.rs b/crates/db_schema/src/traits.rs index 4f24b9766..f690c22bf 100644 --- a/crates/db_schema/src/traits.rs +++ b/crates/db_schema/src/traits.rs @@ -1,42 +1,108 @@ use crate::{ newtypes::{CommunityId, DbUrl, PersonId}, - utils::{DbPool,get_conn}, + utils::{get_conn, DbPool, DbConn}, }; -use diesel::{result::Error,Identifiable, associations::HasTable,query_dsl::methods::FindDsl}; +use diesel::{ + associations::HasTable, + backend::Backend, + deserialize::{FromSqlRow, Queryable}, + dsl::insert_into, + pg::Pg, + query_builder::{AsQuery, IntoUpdateTarget, Query, QueryFragment, QueryId}, + query_dsl::methods::FindDsl, + result::Error, + AsChangeset, + Column, + Expression, + Identifiable, + Insertable, + QuerySource, + Table, + query_dsl::methods::LimitDsl, +}; +use diesel_async::{AsyncConnection, RunQueryDsl,methods::LoadQuery}; +use std::hash::Hash; #[async_trait] -pub trait Crud where Self: Identifiable, Self::Table: FindDsl { +pub trait Crud +where + Self: Send + HasTable + Send + 'static + FromSqlRow<::SqlType, Pg>, + Self::Table: Send + FindDsl, + >::Output: LimitDsl + Send, + for<'conn> <>::Output as LimitDsl>::Output: + Send + LoadQuery<'static, DbConn<'conn>, Self> /*+ 'query*/ + Send, + ::SqlType: Send, +{ type InsertForm; type UpdateForm; + type IdType: Hash + Eq + Send; async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result where - Self: Sized; - async fn read(pool: &mut DbPool<'_>, id: Self::Id) -> Result + Self: Sized; /*{ + let conn = &mut get_conn(pool).await?; + insert_into(Self::table()) + .values(form) + .get_result::(conn) + .await + }*/ + async fn read(pool: &mut DbPool<'_>, id: Self::IdType) -> Result where - Self: Sized; + Self: Sized, + { + let mut conn = get_conn(pool).await?; + let table = Self::table(); + let find_dsl_output = FindDsl::find(table, id); + RunQueryDsl::first::(find_dsl_output, &mut conn).await + } /// 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::Id, + id: Self::IdType, form: &Self::UpdateForm, ) -> Result where - Self: Sized; - async fn delete(_pool: &mut DbPool<'_>, _id: Self::Id) -> Result + Self: Sized; /*{ + let conn = &mut get_conn(pool).await?; + diesel::update(Self::table().find(id)) + .set(form) + .get_result::(conn) + .await + }*/ + async fn delete(pool: &mut DbPool<'_>, id: Self::IdType) -> Result where Self: Sized, - Self::Id: Send, + Self::IdType: Send, { - async { Err(Error::NotFound) }.await + Err(Error::NotFound) + /*let conn = &mut get_conn(pool).await?; + diesel::delete(Self::table().find(id)).execute(conn).await*/ } } #[async_trait] -pub trait Followable { +pub trait Followable +where + Self: HasTable, + for<'a> &'a Self::Form: AsChangeset + Insertable, +{ + //type FollowerColumn: Column + Default + Send; + //type TargetColumn: Column + Default + Send; type Form; async fn follow(pool: &mut DbPool<'_>, form: &Self::Form) -> Result where - Self: Sized; + Self: Sized; /*{ + let conn = &mut get_conn(pool).await?; + insert_into(Self::table()) + .values(form) + .on_conflict(( + Self::TargetColumn::default(), + Self::FollowerColumn::default(), + )) + .do_update() + .set(form) + .get_result::(conn) + .await + }*/ async fn follow_accepted( pool: &mut DbPool<'_>, community_id: CommunityId, @@ -70,7 +136,7 @@ pub trait Likeable { async fn remove( pool: &mut DbPool<'_>, person_id: PersonId, - item_id: Self::Id, + item_id: Self::IdType, ) -> Result where Self: Sized; @@ -129,14 +195,14 @@ pub trait Reportable { Self: Sized; async fn resolve( pool: &mut DbPool<'_>, - report_id: Self::Id, + report_id: Self::IdType, resolver_id: PersonId, ) -> Result where Self: Sized; async fn unresolve( pool: &mut DbPool<'_>, - report_id: Self::Id, + report_id: Self::IdType, resolver_id: PersonId, ) -> Result where