add create_viele_typen

This commit is contained in:
Peter Schiwy 2024-06-04 15:38:07 +02:00
parent 85f1840d7b
commit bb1946bb83
8 changed files with 89 additions and 61 deletions

View File

@ -1,5 +1,5 @@
-- Add up migration script here -- Add up migration script here
CREATE TABLE IF NOT EXISTS typen ( CREATE TABLE IF NOT EXISTS typen (
typ_id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL name VARCHAR NOT NULL
); );

View File

@ -1,5 +1,5 @@
-- Add up migration script here -- Add up migration script here
CREATE TABLE IF NOT EXISTS hersteller ( CREATE TABLE IF NOT EXISTS hersteller (
hersteller_id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL name VARCHAR NOT NULL
); );

View File

@ -1,9 +1,9 @@
-- Add up migration script here -- Add up migration script here
CREATE TABLE IF NOT EXISTS modelle ( CREATE TABLE IF NOT EXISTS modelle (
modell_id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL, name VARCHAR NOT NULL,
typ_id SERIAL, typ_id SERIAL,
hersteller_id SERIAL, hersteller_id SERIAL,
CONSTRAINT fk_typ FOREIGN KEY(typ_id) REFERENCES typen(typ_id) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT fk_typ FOREIGN KEY(typ_id) REFERENCES typen(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_hersteller FOREIGN KEY (hersteller_id) REFERENCES hersteller(hersteller_id) ON DELETE NO ACTION ON UPDATE NO ACTION CONSTRAINT fk_hersteller FOREIGN KEY (hersteller_id) REFERENCES hersteller(id) ON DELETE NO ACTION ON UPDATE NO ACTION
) )

View File

@ -6,38 +6,34 @@ use sqlx::{FromRow, PgPool};
#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, sqlx::Type)] #[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, sqlx::Type)]
pub struct Hersteller { pub struct Hersteller {
/// Die Datenbank-ID /// Die Datenbank-ID
pub hersteller_id: i32, pub id: i32,
/// Der Name eines Herstellers /// Der Name eines Herstellers
name: String, name: String,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct HerstellerCreateInput { pub struct HerstellerCreateInput {
pub name: String, pub name: String,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct HerstellerUpdateInput { pub struct HerstellerUpdateInput {
pub hersteller_id: i32, pub id: i32,
pub name: Option<String>, pub name: Option<String>,
} }
impl Hersteller { impl Hersteller {
pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Hersteller> { pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Hersteller> {
let row = sqlx::query_as!( let row = sqlx::query_as!(Hersteller, "SELECT * FROM hersteller WHERE id = $1", id)
Hersteller, .fetch_one(pool)
"SELECT * FROM hersteller WHERE hersteller_id = $1", .await?;
id
)
.fetch_one(pool)
.await?;
Ok(row) Ok(row)
} }
pub async fn read_all(pool: &PgPool) -> Result<Vec<Hersteller>> { pub async fn read_all(pool: &PgPool) -> Result<Vec<Hersteller>> {
let rows = sqlx::query_as!(Hersteller, "SELECT hersteller_id, name FROM hersteller") let rows = sqlx::query_as!(Hersteller, "SELECT id, name FROM hersteller")
.fetch_all(pool) .fetch_all(pool)
.await?; .await?;
@ -46,32 +42,32 @@ impl Hersteller {
pub async fn create(pool: &PgPool, input: &HerstellerCreateInput) -> Result<Hersteller> { pub async fn create(pool: &PgPool, input: &HerstellerCreateInput) -> Result<Hersteller> {
let row = sqlx::query!( let row = sqlx::query!(
"INSERT INTO hersteller(name) VALUES ($1) RETURNING hersteller_id", "INSERT INTO hersteller(name) VALUES ($1) RETURNING id",
input.name input.name
) )
.fetch_one(pool) .fetch_one(pool)
.await?; .await?;
let result = Self::read_one(pool, &row.hersteller_id).await?; let result = Self::read_one(pool, &row.id).await?;
Ok(result) Ok(result)
} }
pub async fn update(pool: &PgPool, input: &HerstellerUpdateInput) -> Result<Hersteller> { pub async fn update(pool: &PgPool, input: &HerstellerUpdateInput) -> Result<Hersteller> {
sqlx::query!( sqlx::query!(
"UPDATE hersteller SET name=$1 WHERE hersteller_id = $2", "UPDATE hersteller SET name=$1 WHERE id = $2",
input.name, input.name,
input.hersteller_id input.id
) )
.execute(pool) .execute(pool)
.await?; .await?;
let t = Hersteller::read_one(pool, &input.hersteller_id).await?; let t = Hersteller::read_one(pool, &input.id).await?;
Ok(t) Ok(t)
} }
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> { pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
let result = sqlx::query!("DELETE FROM hersteller WHERE hersteller_id = $1", id) let result = sqlx::query!("DELETE FROM hersteller WHERE id = $1", id)
.execute(pool) .execute(pool)
.await?; .await?;

View File

@ -5,10 +5,10 @@ use sqlx::{FromRow, PgPool};
use super::{hersteller::Hersteller, typ::Typ}; use super::{hersteller::Hersteller, typ::Typ};
#[derive(SimpleObject, FromRow, Deserialize, Serialize)] #[derive(SimpleObject, FromRow, Deserialize, Serialize, Debug)]
pub struct Modell { pub struct Modell {
/// Die Datenbank-ID /// Die Datenbank-ID
pub modell_id: i32, pub id: i32,
/// Der Geräte-Typ z.B. Monitor /// Der Geräte-Typ z.B. Monitor
typ: Typ, typ: Typ,
@ -20,16 +20,16 @@ pub struct Modell {
name: String, name: String,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct ModellCreateInput { pub struct ModellCreateInput {
pub name: String, pub name: String,
pub typ_id: i32, pub typ_id: i32,
pub hersteller_id: i32, pub hersteller_id: i32,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct ModellUpdateInput { pub struct ModellUpdateInput {
pub modell_id: i32, pub id: i32,
pub name: Option<String>, pub name: Option<String>,
pub typ_id: Option<i32>, pub typ_id: Option<i32>,
pub hersteller_id: Option<i32>, pub hersteller_id: Option<i32>,
@ -41,13 +41,13 @@ impl Modell {
Modell, Modell,
r#" r#"
select select
m.modell_id, m.name, m.id, m.name,
(t.typ_id, t.name) as "typ!: Typ", (t.id, t.name) as "typ!: Typ",
(h.hersteller_id, h.name) as "hersteller!: Hersteller" (h.id, h.name) as "hersteller!: Hersteller"
from modelle as m from modelle as m
join typen as t using(typ_id) join typen as t on t.id = m.typ_id
join hersteller as h using(hersteller_id) join hersteller as h on h.id = m.hersteller_id
where m.modell_id = $1; where m.id = $1;
"#, "#,
id id
) )
@ -62,12 +62,12 @@ impl Modell {
Modell, Modell,
r#" r#"
select select
m.modell_id, m.name, m.id, m.name,
(t.typ_id, t.name) as "typ!: Typ", (t.id, t.name) as "typ!: Typ",
(h.hersteller_id, h.name) as "hersteller!: Hersteller" (h.id, h.name) as "hersteller!: Hersteller"
from modelle as m from modelle as m
join typen as t using(typ_id) join typen as t on t.id = m.typ_id
join hersteller as h using(hersteller_id) join hersteller as h on h.id = m.hersteller_id
"# "#
) )
.fetch_all(pool) .fetch_all(pool)
@ -77,32 +77,36 @@ impl Modell {
} }
pub async fn create(pool: &PgPool, input: &ModellCreateInput) -> Result<Modell> { pub async fn create(pool: &PgPool, input: &ModellCreateInput) -> Result<Modell> {
let row = sqlx::query!(r#"INSERT INTO modelle(typ_id, hersteller_id, name) VALUES ($1, $2, $3) RETURNING modell_id"#, input.typ_id, input.hersteller_id, input.name let row = sqlx::query!(
r#"INSERT INTO modelle(typ_id, hersteller_id, name) VALUES ($1, $2, $3) RETURNING id"#,
input.typ_id,
input.hersteller_id,
input.name
) )
.fetch_one(pool) .fetch_one(pool)
.await?; .await?;
Self::read_one(pool, &row.modell_id).await Self::read_one(pool, &row.id).await
} }
pub async fn update(pool: &PgPool, input: &ModellUpdateInput) -> Result<Modell> { pub async fn update(pool: &PgPool, input: &ModellUpdateInput) -> Result<Modell> {
sqlx::query!( sqlx::query!(
"UPDATE modelle SET name=COALESCE($1, name), typ_id=COALESCE($2, typ_id), hersteller_id=COALESCE($3, hersteller_id) WHERE modell_id = $4", "UPDATE modelle SET name=COALESCE($1, name), typ_id=COALESCE($2, typ_id), hersteller_id=COALESCE($3, hersteller_id) WHERE id = $4",
input.name, input.name,
input.typ_id, input.typ_id,
input.hersteller_id, input.hersteller_id,
input.modell_id input.id
) )
.execute(pool) .execute(pool)
.await?; .await?;
let t = Modell::read_one(pool, &input.modell_id).await?; let t = Modell::read_one(pool, &input.id).await?;
Ok(t) Ok(t)
} }
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> { pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
let result = sqlx::query!("DELETE FROM modelle WHERE modell_id = $1", id) let result = sqlx::query!("DELETE FROM modelle WHERE id = $1", id)
.execute(pool) .execute(pool)
.await?; .await?;

View File

@ -5,26 +5,26 @@ use sqlx::{FromRow, PgPool, Type};
#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, Type)] #[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, Type)]
pub struct Typ { pub struct Typ {
pub typ_id: i32, pub id: i32,
/// Name eines Typs /// Name eines Typs
pub name: String, pub name: String,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct TypCreateInput { pub struct TypCreateInput {
pub name: String, pub name: String,
} }
#[derive(InputObject)] #[derive(InputObject, Debug)]
pub struct TypUpdateInput { pub struct TypUpdateInput {
pub typ_id: i32, pub id: i32,
pub name: Option<String>, pub name: Option<String>,
} }
impl Typ { impl Typ {
pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Typ> { pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Typ> {
let row = sqlx::query_as!(Typ, "SELECT * FROM typen WHERE typ_id = $1", id) let row = sqlx::query_as!(Typ, "SELECT * FROM typen WHERE id = $1", id)
.fetch_one(pool) .fetch_one(pool)
.await?; .await?;
@ -32,7 +32,7 @@ impl Typ {
} }
pub async fn read_all(pool: &PgPool) -> Result<Vec<Typ>> { pub async fn read_all(pool: &PgPool) -> Result<Vec<Typ>> {
let rows = sqlx::query_as!(Typ, "SELECT typ_id, name FROM typen") let rows = sqlx::query_as!(Typ, "SELECT id, name FROM typen")
.fetch_all(pool) .fetch_all(pool)
.await?; .await?;
@ -41,32 +41,49 @@ impl Typ {
pub async fn create(pool: &PgPool, input: TypCreateInput) -> Result<Typ> { pub async fn create(pool: &PgPool, input: TypCreateInput) -> Result<Typ> {
let row = sqlx::query!( let row = sqlx::query!(
"INSERT INTO typen(name) VALUES ($1) RETURNING typ_id", "INSERT INTO typen(name) VALUES ($1) RETURNING id",
input.name input.name
) )
.fetch_one(pool) .fetch_one(pool)
.await?; .await?;
let result = Self::read_one(pool, &row.typ_id).await?; let result = Self::read_one(pool, &row.id).await?;
Ok(result) Ok(result)
} }
pub async fn create_many(pool: &PgPool, input: &[TypCreateInput]) -> Result<Typ> {
let mut v1: Vec<&str> = Vec::new();
input.iter().for_each(|typ| v1.push(&typ.name));
let row = sqlx::query_as(
r#"
INSERT INTO typen(name)
SELECT * FROM UNNEST($1)
RETURNING id, name"#,
)
.bind(&v1)
.fetch_one(pool)
.await?;
Ok(row)
}
pub async fn update(pool: &PgPool, input: TypUpdateInput) -> Result<Typ> { pub async fn update(pool: &PgPool, input: TypUpdateInput) -> Result<Typ> {
sqlx::query!( sqlx::query!(
"UPDATE typen SET name=$1 WHERE typ_id = $2", "UPDATE typen SET name=$1 WHERE id = $2",
input.name, input.name,
input.typ_id input.id
) )
.execute(pool) .execute(pool)
.await?; .await?;
let t = Typ::read_one(pool, &input.typ_id).await?; let t = Typ::read_one(pool, &input.id).await?;
Ok(t) Ok(t)
} }
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> { pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
let result = sqlx::query!("DELETE FROM typen WHERE typ_id = $1", id) let result = sqlx::query!("DELETE FROM typen WHERE id = $1", id)
.execute(pool) .execute(pool)
.await?; .await?;

View File

@ -10,20 +10,20 @@ impl ModellMutation {
async fn create_modell( async fn create_modell(
&self, &self,
ctx: &Context<'_>, ctx: &Context<'_>,
modell: ModellCreateInput, input: ModellCreateInput,
) -> FieldResult<Modell> { ) -> FieldResult<Modell> {
let pool = ctx.data::<PgPool>()?; let pool = ctx.data::<PgPool>()?;
let row = Modell::create(pool, &modell).await?; let row = Modell::create(pool, &input).await?;
Ok(row) Ok(row)
} }
async fn update_modell( async fn update_modell(
&self, &self,
ctx: &Context<'_>, ctx: &Context<'_>,
modell: ModellUpdateInput, input: ModellUpdateInput,
) -> FieldResult<Modell> { ) -> FieldResult<Modell> {
let pool = ctx.data::<PgPool>()?; let pool = ctx.data::<PgPool>()?;
let row = Modell::update(pool, &modell).await?; let row = Modell::update(pool, &input).await?;
Ok(row) Ok(row)
} }
async fn delete_modell(&self, ctx: &Context<'_>, id: i32) -> FieldResult<bool> { async fn delete_modell(&self, ctx: &Context<'_>, id: i32) -> FieldResult<bool> {

View File

@ -13,6 +13,17 @@ impl TypMutation {
Ok(row) Ok(row)
} }
async fn create_viele_typen(
&self,
ctx: &Context<'_>,
input: Vec<TypCreateInput>,
) -> FieldResult<Typ> {
let pool = ctx.data::<PgPool>()?;
let row = Typ::create_many(pool, &input).await?;
Ok(row)
}
async fn update_typ(&self, ctx: &Context<'_>, input: TypUpdateInput) -> FieldResult<Typ> { async fn update_typ(&self, ctx: &Context<'_>, input: TypUpdateInput) -> FieldResult<Typ> {
let pool = ctx.data::<PgPool>()?; let pool = ctx.data::<PgPool>()?;
let row = Typ::update(pool, input).await?; let row = Typ::update(pool, input).await?;