create gruppen, rollen, etc...

This commit is contained in:
Peter Schiwy
2024-12-06 14:06:27 +01:00
parent bfce29c8ee
commit 623d28f77b
63 changed files with 735 additions and 185 deletions

View File

@@ -0,0 +1 @@
pub mod gruppen;

View File

@@ -0,0 +1,24 @@
use async_graphql::dataloader::*;
use async_graphql::*;
use std::collections::HashMap;
use std::sync::Arc;
use crate::domain::gruppe::model::Gruppe;
use crate::domain::gruppe::service::Service;
use crate::scalar::Id;
pub struct GruppenLoader {
pub pool: sqlx::PgPool,
}
impl Loader<Id> for GruppenLoader {
type Value = Vec<Gruppe>;
type Error = Arc<sqlx::Error>;
async fn load(&self, keys: &[Id]) -> Result<HashMap<Id, Self::Value>, Self::Error> {
let rows = Service::new(self.pool.clone())
.gruppe_dataloader(keys)
.await?;
Ok(rows)
}
}

View File

@@ -0,0 +1,2 @@
pub mod gruppe;
pub use gruppe::Gruppe;

View File

@@ -0,0 +1,8 @@
use crate::scalar::{Id, Time};
pub struct Gruppe {
pub id: Id,
pub gruppenname: String,
pub erstellt_am: Option<Time>,
pub geaendert_am: Option<Time>,
}

View File

@@ -0,0 +1,7 @@
pub mod gruppe;
pub mod gruppe_erstelle_input;
pub mod gruppe_update_input;
pub use gruppe::Gruppe;
pub use gruppe_erstelle_input::GruppeErstelleInput;
pub use gruppe_update_input::GruppeUpdateInput;

View File

@@ -0,0 +1,22 @@
use async_graphql::{ComplexObject, SimpleObject};
use crate::scalar::{Id, Time};
#[derive(sqlx::FromRow, SimpleObject, Clone, Debug)]
#[graphql(complex)]
pub struct Gruppe {
/// Die UUIDl einer Gruppe
pub id: Id,
/// Der Gruppenname
pub gruppenname: String,
/// Wann die Gruppe erstellt wurde
pub erstellt_am: Time,
/// Wann die Gruppe geaendert wurde
pub geaendert_am: Time,
}
#[ComplexObject]
impl Gruppe {}

View File

@@ -0,0 +1,7 @@
use async_graphql::InputObject;
#[derive(InputObject)]
pub struct GruppeErstelleInput {
/// Der Name einer Gruppe
pub gruppenname: String,
}

View File

@@ -0,0 +1,7 @@
use async_graphql::InputObject;
#[derive(InputObject)]
pub struct GruppeUpdateInput {
/// Der Name einer Gruppe
pub gruppenname: String,
}

View File

@@ -0,0 +1,19 @@
mod gruppe_alle;
mod gruppe_dataloader;
mod gruppe_erstellen;
mod gruppe_update;
#[derive(Debug, Clone)]
pub struct Repository {}
impl Repository {
pub fn new() -> Repository {
Repository {}
}
}
impl Default for Repository {
fn default() -> Self {
Self::new()
}
}

View File

@@ -0,0 +1,21 @@
use anyhow::Error;
use super::Repository;
use crate::{database::Queryer, domain::gruppe::model};
impl Repository {
pub async fn gruppe_alle<'c, C: Queryer<'c>>(
&self,
db: C,
) -> Result<Vec<model::Gruppe>, Error> {
const QUERY: &str = r#"
SELECT * FROM gruppen
"#;
let gruppen = sqlx::query_as::<_, model::Gruppe>(QUERY)
.fetch_all(db)
.await?;
Ok(gruppen)
}
}

View File

@@ -0,0 +1,49 @@
use std::collections::HashMap;
use std::sync::Arc;
use itertools::Itertools;
use super::Repository;
use crate::database::Queryer;
use crate::domain::gruppe::model::Gruppe;
use crate::scalar::Id;
impl Repository {
pub async fn gruppe_dataloader<'c, C: Queryer<'c>>(
&self,
db: C,
keys: &[Id],
) -> Result<HashMap<Id, Vec<Gruppe>>, Arc<sqlx::Error>> {
let rows = sqlx::query!(
r#"
SELECT
bg.benutzer_id,
g.id,
g.gruppenname,
g.erstellt_am,
g.geaendert_am
FROM gruppen AS g
LEFT JOIN benutzer_gruppen AS bg ON g.id = bg.gruppe_id
WHERE bg.benutzer_id = ANY($1);
"#,
keys
)
.fetch_all(db)
.await?
.into_iter()
.map(|row| {
(
row.benutzer_id,
Gruppe {
id: row.id,
gruppenname: row.gruppenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
Ok(rows)
}
}

View File

@@ -0,0 +1,29 @@
use anyhow::Error;
use super::Repository;
use crate::database::Queryer;
use crate::domain::gruppe::{entity, model};
impl Repository {
pub async fn gruppe_erstellen<'c, C: Queryer<'c>>(
&self,
db: C,
gruppe: &entity::Gruppe,
) -> Result<model::Gruppe, Error> {
const QUERY: &str = r#"
INSERT INTO gruppen (id, erstellt_am, geaendert_am, gruppenname) VALUES (
$1, $2, $3, $4
) RETURNING id, erstellt_am, geaendert_am, gruppenname;
"#;
let gruppe = sqlx::query_as::<_, model::Gruppe>(QUERY)
.bind(gruppe.id)
.bind(gruppe.erstellt_am)
.bind(gruppe.geaendert_am)
.bind(&gruppe.gruppenname)
.fetch_one(db)
.await?;
Ok(gruppe)
}
}

View File

@@ -0,0 +1,28 @@
use anyhow::Error;
use super::Repository;
use crate::database::Queryer;
use crate::domain::gruppe::{entity, model};
impl Repository {
pub async fn gruppe_update<'c, C: Queryer<'c>>(
&self,
db: C,
gruppe: &entity::Gruppe,
) -> Result<model::Gruppe, Error> {
const QUERY: &str = r#"
UPDATE gruppen
SET geaendert_am = $2, ruppenname = $3 WHERE gruppeid = $1
RETURNING id, geaendert_am, gruppenname, gruppenname;
"#;
let gruppe = sqlx::query_as::<_, model::Gruppe>(QUERY)
.bind(gruppe.id)
.bind(gruppe.geaendert_am)
.bind(&gruppe.gruppenname)
.fetch_one(db)
.await?;
Ok(gruppe)
}
}

View File

@@ -0,0 +1,20 @@
mod gruppe_alle;
mod gruppe_dataloader;
mod gruppe_erstellen;
mod gruppe_update;
use super::repository::Repository;
use crate::database::DB;
#[derive(Debug)]
pub struct Service {
repo: Repository,
pub db: DB,
}
impl Service {
pub fn new(db: DB) -> Self {
let repo = Repository::new();
Self { repo, db }
}
}

View File

@@ -0,0 +1,12 @@
use anyhow::Error;
use crate::domain::gruppe::model;
use super::Service;
impl Service {
pub async fn gruppe_alle(&self) -> Result<Vec<model::Gruppe>, Error> {
let gruppe = self.repo.gruppe_alle(&self.db).await?;
Ok(gruppe)
}
}

View File

@@ -0,0 +1,15 @@
use std::{collections::HashMap, sync::Arc};
use crate::{domain::gruppe::model::Gruppe, scalar::Id};
use super::Service;
impl Service {
pub async fn gruppe_dataloader(
&self,
keys: &[Id],
) -> Result<HashMap<Id, Vec<Gruppe>>, Arc<sqlx::Error>> {
let grupen_dataloader = self.repo.gruppe_dataloader(&self.db, keys).await?;
Ok(grupen_dataloader)
}
}

View File

@@ -0,0 +1,26 @@
use anyhow::Error;
use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::gruppe::{
entity,
model::{self, GruppeErstelleInput},
};
impl Service {
pub async fn gruppe_erstellen(
&self,
input: GruppeErstelleInput,
) -> Result<model::Gruppe, Error> {
let gruppe_input = entity::Gruppe {
id: Ulid::new().into(),
gruppenname: input.gruppenname,
erstellt_am: Some(Utc::now()),
geaendert_am: Some(Utc::now()),
};
let gruppe = self.repo.gruppe_erstellen(&self.db, &gruppe_input).await?;
Ok(gruppe)
}
}

View File

@@ -0,0 +1,23 @@
use anyhow::Error;
use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::gruppe::{
entity,
model::{self, GruppeUpdateInput},
};
impl Service {
pub async fn gruppe_update(&self, input: GruppeUpdateInput) -> Result<model::Gruppe, Error> {
let gruppe_input = entity::Gruppe {
id: Ulid::new().into(),
gruppenname: input.gruppenname,
erstellt_am: None,
geaendert_am: Some(Utc::now()),
};
let gruppe = self.repo.gruppe_erstellen(&self.db, &gruppe_input).await?;
Ok(gruppe)
}
}