X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_views%2Fsrc%2Flocal_user_view.rs;h=23a8b8f0517a6b7d14ea9d3ba693af0aee65cba6;hb=9a5a13c734a1792511e1bfef7b9ac4121e0e7371;hp=85a83e1569a040ad8465f0ee30c42ea78f8279bd;hpb=05b485b6786e4946d6773e0ef59a94266b342a74;p=lemmy.git diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index 85a83e15..23a8b8f0 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -1,147 +1,118 @@ -use diesel::{result::Error, *}; -use lemmy_db_queries::{aggregates::person_aggregates::PersonAggregates, ToSafe, ToSafeSettings}; +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}, - }, - LocalUserId, - PersonId, + source::{local_user::LocalUser, person::Person}, + traits::JoinView, + utils::{functions::lower, DbConn, DbPool, ListFn, Queries, ReadFn}, }; -use serde::Serialize; -#[derive(Debug, Serialize, Clone)] -pub struct LocalUserView { - pub local_user: LocalUser, - pub person: Person, - pub counts: PersonAggregates, +type LocalUserViewTuple = (LocalUser, Person, PersonAggregates); + +enum ReadBy<'a> { + Id(LocalUserId), + Person(PersonId), + Name(&'a str), + NameOrEmail(&'a str), + Email(&'a str), } -type LocalUserViewTuple = (LocalUser, Person, PersonAggregates); +enum ListMode { + AdminsWithEmails, +} -impl LocalUserView { - pub fn read(conn: &PgConnection, local_user_id: LocalUserId) -> Result { - let (local_user, person, counts) = local_user::table - .find(local_user_id) - .inner_join(person::table) +fn queries<'a>( +) -> Queries>, impl ListFn<'a, LocalUserView, ListMode>> { + let selection = ( + local_user::all_columns, + person::all_columns, + person_aggregates::all_columns, + ); + + 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)), + ), + _ => query, + }; + query .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, - }) + .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 read_person(conn: &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, - }) + pub async fn read_person(pool: &mut DbPool<'_>, person_id: PersonId) -> Result { + queries().read(pool, ReadBy::Person(person_id)).await } - // TODO check where this is used - pub fn read_from_name(conn: &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 { - person, - counts, - local_user, - }) + pub async fn read_from_name(pool: &mut DbPool<'_>, name: &str) -> Result { + queries().read(pool, ReadBy::Name(name)).await } - pub fn find_by_email_or_name(conn: &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( - person::name - .ilike(name_or_email) - .or(local_user::email.ilike(name_or_email)), - ) - .select(( - local_user::all_columns, - person::all_columns, - person_aggregates::all_columns, - )) - .first::(conn)?; - Ok(Self { - person, - counts, - local_user, - }) + 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 find_by_email(conn: &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 { - person, - counts, - local_user, - }) + pub async fn find_by_email(pool: &mut DbPool<'_>, from_email: &str) -> Result { + queries().read(pool, ReadBy::Email(from_email)).await } -} -#[derive(Debug, Serialize, Clone)] -pub struct LocalUserSettingsView { - pub local_user: LocalUserSettings, - pub person: PersonSafe, - pub counts: PersonAggregates, + pub async fn list_admins_with_emails(pool: &mut DbPool<'_>) -> Result, Error> { + queries().list(pool, ListMode::AdminsWithEmails).await + } } -type LocalUserSettingsViewTuple = (LocalUserSettings, PersonSafe, PersonAggregates); - -impl LocalUserSettingsView { - pub fn read(conn: &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 { - person, - counts, - local_user, - }) +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, + } } }