create gruppen, rollen, etc...
This commit is contained in:
1
src/domain/gruppe/dataloader.rs
Normal file
1
src/domain/gruppe/dataloader.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod gruppen;
|
||||
24
src/domain/gruppe/dataloader/gruppen.rs
Normal file
24
src/domain/gruppe/dataloader/gruppen.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
2
src/domain/gruppe/entity.rs
Normal file
2
src/domain/gruppe/entity.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod gruppe;
|
||||
pub use gruppe::Gruppe;
|
||||
8
src/domain/gruppe/entity/gruppe.rs
Normal file
8
src/domain/gruppe/entity/gruppe.rs
Normal 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>,
|
||||
}
|
||||
7
src/domain/gruppe/model.rs
Normal file
7
src/domain/gruppe/model.rs
Normal 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;
|
||||
22
src/domain/gruppe/model/gruppe.rs
Normal file
22
src/domain/gruppe/model/gruppe.rs
Normal 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 {}
|
||||
7
src/domain/gruppe/model/gruppe_erstelle_input.rs
Normal file
7
src/domain/gruppe/model/gruppe_erstelle_input.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use async_graphql::InputObject;
|
||||
|
||||
#[derive(InputObject)]
|
||||
pub struct GruppeErstelleInput {
|
||||
/// Der Name einer Gruppe
|
||||
pub gruppenname: String,
|
||||
}
|
||||
7
src/domain/gruppe/model/gruppe_update_input.rs
Normal file
7
src/domain/gruppe/model/gruppe_update_input.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use async_graphql::InputObject;
|
||||
|
||||
#[derive(InputObject)]
|
||||
pub struct GruppeUpdateInput {
|
||||
/// Der Name einer Gruppe
|
||||
pub gruppenname: String,
|
||||
}
|
||||
19
src/domain/gruppe/repository.rs
Normal file
19
src/domain/gruppe/repository.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
21
src/domain/gruppe/repository/gruppe_alle.rs
Normal file
21
src/domain/gruppe/repository/gruppe_alle.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
49
src/domain/gruppe/repository/gruppe_dataloader.rs
Normal file
49
src/domain/gruppe/repository/gruppe_dataloader.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
29
src/domain/gruppe/repository/gruppe_erstellen.rs
Normal file
29
src/domain/gruppe/repository/gruppe_erstellen.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
28
src/domain/gruppe/repository/gruppe_update.rs
Normal file
28
src/domain/gruppe/repository/gruppe_update.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
20
src/domain/gruppe/service.rs
Normal file
20
src/domain/gruppe/service.rs
Normal 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 }
|
||||
}
|
||||
}
|
||||
12
src/domain/gruppe/service/gruppe_alle.rs
Normal file
12
src/domain/gruppe/service/gruppe_alle.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
15
src/domain/gruppe/service/gruppe_dataloader.rs
Normal file
15
src/domain/gruppe/service/gruppe_dataloader.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
26
src/domain/gruppe/service/gruppe_erstellen.rs
Normal file
26
src/domain/gruppe/service/gruppe_erstellen.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
23
src/domain/gruppe/service/gruppe_update.rs
Normal file
23
src/domain/gruppe/service/gruppe_update.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user