diff --git a/src/dataloader/benutzer_gruppen_kumulativ.rs b/src/dataloader/benutzer_gruppen_kumulativ.rs deleted file mode 100644 index bf4d051..0000000 --- a/src/dataloader/benutzer_gruppen_kumulativ.rs +++ /dev/null @@ -1,72 +0,0 @@ -// use async_graphql::dataloader::*; -// use async_graphql::*; -// use itertools::Itertools; -// use std::collections::HashMap; -// use std::sync::Arc; -// -// use crate::models::gruppe_ansicht::{GruppeAnsicht, Herkunft}; -// use crate::scalar::Id; -// -// pub struct BenutzerGruppenKumulativLoader { -// pub pool: sqlx::PgPool, -// } -// -// impl Loader for BenutzerGruppenKumulativLoader { -// type Value = Vec; -// type Error = Arc; -// -// async fn load(&self, keys: &[Id]) -> Result, Self::Error> { -// let rows = sqlx::query!( -// r#" -// SELECT DISTINCT -// COALESCE(bg.benutzer_id, br.benutzer_id) AS benutzer_id, -// g.id AS gruppe_id, -// g.gruppenname, -// g.erstellt_am, -// g.geaendert_am, -// CASE WHEN br.benutzer_id IS NOT null THEN r.rollenname END AS rollenname, -// CASE -// WHEN bg.benutzer_id IS NOT NULL AND br.benutzer_id IS NOT NULL THEN 'beides'::gruppen_herkunft -// WHEN bg.benutzer_id IS NOT NULL THEN 'direkt'::gruppen_herkunft -// WHEN br.benutzer_id IS NOT NULL THEN 'indirekt'::gruppen_herkunft -// END AS "herkunft: Herkunft" -// FROM gruppen AS g -// LEFT JOIN -// benutzer_gruppen AS bg -// ON -// g.id = bg.gruppe_id -// AND bg.benutzer_id = ANY($1) -// LEFT JOIN rollen_gruppen AS rg ON g.id = rg.gruppe_id -// LEFT JOIN -// benutzer_rollen AS br -// ON -// rg.rolle_id = br.rolle_id -// AND br.benutzer_id = ANY($1) -// LEFT JOIN rollen AS r ON rg.rolle_id = r.id -// WHERE -// bg.benutzer_id = ANY($1) -// OR br.benutzer_id = ANY($1); -// "#, -// keys -// ) -// .fetch_all(&self.pool) -// .await? -// .into_iter() -// .map(|row| { -// ( -// row.benutzer_id.unwrap(), -// GruppeAnsicht { -// id: row.gruppe_id, -// gruppenname: row.gruppenname, -// rollenname: row.rollenname, -// herkunft: row.herkunft.unwrap(), -// erstellt_am: row.erstellt_am, -// geaendert_am: row.geaendert_am, -// }, -// ) -// }) -// .into_group_map(); -// -// Ok(rows) -// } -// } diff --git a/src/dataloader/benutzer_rollen.rs b/src/dataloader/benutzer_rollen.rs deleted file mode 100644 index 75a6d80..0000000 --- a/src/dataloader/benutzer_rollen.rs +++ /dev/null @@ -1,51 +0,0 @@ -// use async_graphql::dataloader::*; -// use async_graphql::*; -// use itertools::Itertools; -// use std::collections::HashMap; -// use std::sync::Arc; -// -// use crate::domain::rolle::model::Rolle; -// use crate::scalar::Id; -// -// pub struct BenutzerRollenLoader { -// pub pool: sqlx::PgPool, -// } -// -// impl Loader for BenutzerRollenLoader { -// type Value = Vec; -// type Error = Arc; -// -// async fn load(&self, keys: &[Id]) -> Result, Self::Error> { -// let rows = sqlx::query!( -// r#" -// SELECT -// br.benutzer_id, -// r.id, -// r.rollenname, -// r.erstellt_am, -// r.geaendert_am -// FROM rollen AS r -// LEFT JOIN benutzer_rollen AS br ON r.id = br.rolle_id -// WHERE br.benutzer_id = ANY($1); -// "#, -// keys -// ) -// .fetch_all(&self.pool) -// .await? -// .into_iter() -// .map(|row| { -// ( -// row.benutzer_id, -// Rolle { -// id: row.id, -// rollenname: row.rollenname, -// erstellt_am: row.erstellt_am, -// geaendert_am: row.geaendert_am, -// }, -// ) -// }) -// .into_group_map(); -// -// Ok(rows) -// } -// } diff --git a/src/dataloader/mod.rs b/src/dataloader/mod.rs index 68f892b..5fbec7a 100644 --- a/src/dataloader/mod.rs +++ b/src/dataloader/mod.rs @@ -1,6 +1,3 @@ -mod benutzer_gruppen_kumulativ; -mod benutzer_rollen; - use crate::domain::{ gruppe::dataloader::gruppen::GruppenLoader, rolle::dataloader::rollen::RollenLoader, }; diff --git a/src/domain/benutzer/dataloader.rs b/src/domain/benutzer/dataloader.rs index e69de29..4523da9 100644 --- a/src/domain/benutzer/dataloader.rs +++ b/src/domain/benutzer/dataloader.rs @@ -0,0 +1,2 @@ +pub mod benutzer_gruppen_kumulativ; +pub mod benutzer_rollen; diff --git a/src/domain/benutzer/dataloader/benutzer_gruppen_kumulativ.rs b/src/domain/benutzer/dataloader/benutzer_gruppen_kumulativ.rs new file mode 100644 index 0000000..0c6851a --- /dev/null +++ b/src/domain/benutzer/dataloader/benutzer_gruppen_kumulativ.rs @@ -0,0 +1,73 @@ +use async_graphql::dataloader::*; +use async_graphql::*; +use itertools::Itertools; +use std::collections::HashMap; +use std::sync::Arc; + +use crate::domain::benutzer::model::GruppeAnsicht; +use crate::domain::benutzer::model::Herkunft; +use crate::scalar::Id; + +pub struct BenutzerGruppenKumulativLoader { + pub pool: sqlx::PgPool, +} + +impl Loader for BenutzerGruppenKumulativLoader { + type Value = Vec; + type Error = Arc; + + async fn load(&self, keys: &[Id]) -> Result, Self::Error> { + let rows = sqlx::query!( + r#" + SELECT DISTINCT + COALESCE(bg.benutzer_id, br.benutzer_id) AS benutzer_id, + g.id AS gruppe_id, + g.gruppenname, + g.erstellt_am, + g.geaendert_am, + CASE WHEN br.benutzer_id IS NOT null THEN r.rollenname END AS rollenname, + CASE + WHEN bg.benutzer_id IS NOT NULL AND br.benutzer_id IS NOT NULL THEN 'beides'::gruppen_herkunft + WHEN bg.benutzer_id IS NOT NULL THEN 'direkt'::gruppen_herkunft + WHEN br.benutzer_id IS NOT NULL THEN 'indirekt'::gruppen_herkunft + END AS "herkunft: Herkunft" + FROM gruppen AS g + LEFT JOIN + benutzer_gruppen AS bg + ON + g.id = bg.gruppe_id + AND bg.benutzer_id = ANY($1) + LEFT JOIN rollen_gruppen AS rg ON g.id = rg.gruppe_id + LEFT JOIN + benutzer_rollen AS br + ON + rg.rolle_id = br.rolle_id + AND br.benutzer_id = ANY($1) + LEFT JOIN rollen AS r ON rg.rolle_id = r.id + WHERE + bg.benutzer_id = ANY($1) + OR br.benutzer_id = ANY($1); + "#, + keys + ) + .fetch_all(&self.pool) + .await? + .into_iter() + .map(|row| { + ( + row.benutzer_id.unwrap(), + GruppeAnsicht { + id: row.gruppe_id, + gruppenname: row.gruppenname, + rollenname: row.rollenname, + herkunft: row.herkunft.unwrap(), + erstellt_am: row.erstellt_am, + geaendert_am: row.geaendert_am, + }, + ) + }) + .into_group_map(); + + Ok(rows) + } +} diff --git a/src/domain/benutzer/dataloader/benutzer_rollen.rs b/src/domain/benutzer/dataloader/benutzer_rollen.rs new file mode 100644 index 0000000..ade87ab --- /dev/null +++ b/src/domain/benutzer/dataloader/benutzer_rollen.rs @@ -0,0 +1,51 @@ +use async_graphql::dataloader::*; +use async_graphql::*; +use itertools::Itertools; +use std::collections::HashMap; +use std::sync::Arc; + +use crate::domain::rolle::model::Rolle; +use crate::scalar::Id; + +pub struct BenutzerRollenLoader { + pub pool: sqlx::PgPool, +} + +impl Loader for BenutzerRollenLoader { + type Value = Vec; + type Error = Arc; + + async fn load(&self, keys: &[Id]) -> Result, Self::Error> { + let rows = sqlx::query!( + r#" + SELECT + br.benutzer_id, + r.id, + r.rollenname, + r.erstellt_am, + r.geaendert_am + FROM rollen AS r + LEFT JOIN benutzer_rollen AS br ON r.id = br.rolle_id + WHERE br.benutzer_id = ANY($1); + "#, + keys + ) + .fetch_all(&self.pool) + .await? + .into_iter() + .map(|row| { + ( + row.benutzer_id, + Rolle { + id: row.id, + rollenname: row.rollenname, + erstellt_am: row.erstellt_am, + geaendert_am: row.geaendert_am, + }, + ) + }) + .into_group_map(); + + Ok(rows) + } +} diff --git a/src/domain/benutzer/model.rs b/src/domain/benutzer/model.rs index 8e78a54..208c43e 100644 --- a/src/domain/benutzer/model.rs +++ b/src/domain/benutzer/model.rs @@ -1,5 +1,8 @@ pub mod benutzer; pub mod benutzer_create_input; +pub mod benutzer_gruppen_ansicht; pub use benutzer::Benutzer; pub use benutzer_create_input::BenutzerCreateInput; +pub use benutzer_gruppen_ansicht::GruppeAnsicht; +pub use benutzer_gruppen_ansicht::Herkunft; diff --git a/src/domain/benutzer/model/benutzer_gruppen_ansicht.rs b/src/domain/benutzer/model/benutzer_gruppen_ansicht.rs new file mode 100644 index 0000000..273cc29 --- /dev/null +++ b/src/domain/benutzer/model/benutzer_gruppen_ansicht.rs @@ -0,0 +1,43 @@ +use async_graphql::{ComplexObject, Enum, SimpleObject}; +use sqlx::Type; + +use crate::scalar::{Id, Time}; + +/// Aus welcher Quelle die Gruppe stammt. +#[derive(Enum, Clone, Debug, Eq, Copy, PartialEq, Type)] +#[sqlx(type_name = "gruppen_herkunft", rename_all = "lowercase")] +pub enum Herkunft { + /// Die Gruppe wurde direkt dem Benutzer zugefügt + Direkt, + + /// Die Gruppe wurde durch eine Rolle vergeben + Indirekt, + + /// Die Gruppe ist sowohl direkt als auch indirekt zugefügt + Beides, +} + +#[derive(sqlx::FromRow, SimpleObject, Clone, Debug)] +#[graphql(complex)] +pub struct GruppeAnsicht { + /// Die UUID einer Gruppe + pub id: Id, + + /// Der Gruppenname + pub gruppenname: String, + + /// Die Herkunft der Gruppe + pub herkunft: Herkunft, + + /// Bei einer indirekten Zuweisung, wird der Rollenname angegeben + pub rollenname: Option, + + /// Wann die Gruppe erstellt wurde + pub erstellt_am: Time, + + /// Wann die Gruppe geaendert wurde + pub geaendert_am: Time, +} + +#[ComplexObject] +impl GruppeAnsicht {}