X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_views%2Fsrc%2Flocal_user_view.rs;h=23a8b8f0517a6b7d14ea9d3ba693af0aee65cba6;hb=9a5a13c734a1792511e1bfef7b9ac4121e0e7371;hp=b5a758b84e982a736e249fd87adf3f9be04b9087;hpb=ae95f5928e68b8303834c784f955269e6930f28f;p=lemmy.git diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index b5a758b8..23a8b8f0 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -1,167 +1,118 @@ -use crate::structs::{LocalUserSettingsView, LocalUserView}; -use diesel::{result::Error, *}; +use crate::structs::LocalUserView; +use diesel::{result::Error, BoolExpressionMethods, ExpressionMethods, JoinOnDsl, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::PersonAggregates, newtypes::{LocalUserId, PersonId}, schema::{local_user, person, person_aggregates}, - source::{ - local_user::{LocalUser, LocalUserSettings}, - person::{Person, PersonSafe}, - }, - traits::{ToSafe, ToSafeSettings, ViewToVec}, - utils::functions::lower, + source::{local_user::LocalUser, person::Person}, + traits::JoinView, + utils::{functions::lower, DbConn, DbPool, ListFn, Queries, ReadFn}, }; type LocalUserViewTuple = (LocalUser, Person, PersonAggregates); -impl LocalUserView { - pub fn read(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { - let (local_user, person, counts) = local_user::table - .find(local_user_id) - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) - } +enum ReadBy<'a> { + Id(LocalUserId), + Person(PersonId), + Name(&'a str), + NameOrEmail(&'a str), + Email(&'a str), +} - pub fn read_person(conn: &mut PgConnection, person_id: PersonId) -> Result { - let (local_user, person, counts) = local_user::table - .filter(person::id.eq(person_id)) - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) - } +enum ListMode { + AdminsWithEmails, +} - // TODO check where this is used - pub fn read_from_name(conn: &mut PgConnection, name: &str) -> Result { - let (local_user, person, counts) = local_user::table - .filter(person::name.eq(name)) - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) - } +fn queries<'a>( +) -> Queries>, impl ListFn<'a, LocalUserView, ListMode>> { + let selection = ( + local_user::all_columns, + person::all_columns, + person_aggregates::all_columns, + ); - pub fn find_by_email_or_name( - conn: &mut PgConnection, - name_or_email: &str, - ) -> Result { - let (local_user, person, counts) = local_user::table - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .filter( + let read = move |mut conn: DbConn<'a>, search: ReadBy<'a>| async move { + let mut query = local_user::table.into_boxed(); + query = match search { + ReadBy::Id(local_user_id) => query.filter(local_user::id.eq(local_user_id)), + ReadBy::Email(from_email) => query.filter(local_user::email.eq(from_email)), + _ => query, + }; + let mut query = query.inner_join(person::table); + query = match search { + ReadBy::Person(person_id) => query.filter(person::id.eq(person_id)), + ReadBy::Name(name) => query.filter(lower(person::name).eq(name.to_lowercase())), + ReadBy::NameOrEmail(name_or_email) => query.filter( lower(person::name) .eq(lower(name_or_email)) .or(local_user::email.eq(name_or_email)), - ) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) + ), + _ => query, + }; + query + .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) + .select(selection) + .first::(&mut conn) + .await + }; + + let list = move |mut conn: DbConn<'a>, mode: ListMode| async move { + match mode { + ListMode::AdminsWithEmails => { + local_user::table + .filter(local_user::email.is_not_null()) + .filter(person::admin.eq(true)) + .inner_join(person::table) + .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) + .select(selection) + .load::(&mut conn) + .await + } + } + }; + + Queries::new(read, list) +} + +impl LocalUserView { + pub async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result { + queries().read(pool, ReadBy::Id(local_user_id)).await } - pub fn find_by_email(conn: &mut PgConnection, from_email: &str) -> Result { - let (local_user, person, counts) = local_user::table - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .filter(local_user::email.eq(from_email)) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) + pub async fn read_person(pool: &mut DbPool<'_>, person_id: PersonId) -> Result { + queries().read(pool, ReadBy::Person(person_id)).await } -} -type LocalUserSettingsViewTuple = (LocalUserSettings, PersonSafe, PersonAggregates); + pub async fn read_from_name(pool: &mut DbPool<'_>, name: &str) -> Result { + queries().read(pool, ReadBy::Name(name)).await + } -impl LocalUserSettingsView { - pub fn read(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { - let (local_user, person, counts) = local_user::table - .find(local_user_id) - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .select(( - LocalUser::safe_settings_columns_tuple(), - Person::safe_columns_tuple(), - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - local_user, - person, - counts, - }) + pub async fn find_by_email_or_name( + pool: &mut DbPool<'_>, + name_or_email: &str, + ) -> Result { + queries() + .read(pool, ReadBy::NameOrEmail(name_or_email)) + .await } - pub fn list_admins_with_emails(conn: &mut PgConnection) -> Result, Error> { - let res = local_user::table - .filter(person::admin.eq(true)) - .filter(local_user::email.is_not_null()) - .inner_join(person::table) - .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) - .select(( - LocalUser::safe_settings_columns_tuple(), - Person::safe_columns_tuple(), - person_aggregates::all_columns, - )) - .load::(conn)?; + pub async fn find_by_email(pool: &mut DbPool<'_>, from_email: &str) -> Result { + queries().read(pool, ReadBy::Email(from_email)).await + } - Ok(LocalUserSettingsView::from_tuple_to_vec(res)) + pub async fn list_admins_with_emails(pool: &mut DbPool<'_>) -> Result, Error> { + queries().list(pool, ListMode::AdminsWithEmails).await } } -impl ViewToVec for LocalUserSettingsView { - type DbTuple = LocalUserSettingsViewTuple; - fn from_tuple_to_vec(items: Vec) -> Vec { - items - .into_iter() - .map(|a| Self { - local_user: a.0, - person: a.1, - counts: a.2, - }) - .collect::>() +impl JoinView for LocalUserView { + type JoinTuple = LocalUserViewTuple; + fn from_tuple(a: Self::JoinTuple) -> Self { + Self { + local_user: a.0, + person: a.1, + counts: a.2, + } } }