From 6e6918e8ee853e888173dcbd76f1e794d5cf4706 Mon Sep 17 00:00:00 2001 From: Peter Schiwy Date: Mon, 3 Jun 2024 01:53:23 +0200 Subject: [PATCH] sqlx 1:n dependencies --- migrations/20240530193519_typen.up.sql | 2 +- migrations/20240530193528_hersteller.up.sql | 2 +- migrations/20240530193533_modelle.up.sql | 6 +-- src/main.rs | 2 + src/models/hersteller.rs | 32 +++++++++------ src/models/mod.rs | 1 + src/models/modell.rs | 39 ++++-------------- src/models/modell_temp.rs | 44 +++++++++++++++++++++ src/models/typ.rs | 21 +++++----- src/queries/mod.rs | 2 + src/queries/modell_temp.rs | 22 +++++++++++ 11 files changed, 114 insertions(+), 59 deletions(-) create mode 100644 src/models/modell_temp.rs create mode 100644 src/queries/modell_temp.rs diff --git a/migrations/20240530193519_typen.up.sql b/migrations/20240530193519_typen.up.sql index 06a8f77..bb728f5 100644 --- a/migrations/20240530193519_typen.up.sql +++ b/migrations/20240530193519_typen.up.sql @@ -1,5 +1,5 @@ -- Add up migration script here CREATE TABLE typen ( - id SERIAL PRIMARY KEY, + typ_id SERIAL PRIMARY KEY, name VARCHAR NOT NULL ); diff --git a/migrations/20240530193528_hersteller.up.sql b/migrations/20240530193528_hersteller.up.sql index 49e3661..105cbf6 100644 --- a/migrations/20240530193528_hersteller.up.sql +++ b/migrations/20240530193528_hersteller.up.sql @@ -1,5 +1,5 @@ -- Add up migration script here CREATE TABLE hersteller ( - id SERIAL PRIMARY KEY, + hersteller_id SERIAL PRIMARY KEY, name VARCHAR NOT NULL ); diff --git a/migrations/20240530193533_modelle.up.sql b/migrations/20240530193533_modelle.up.sql index d16df40..5fcae37 100644 --- a/migrations/20240530193533_modelle.up.sql +++ b/migrations/20240530193533_modelle.up.sql @@ -1,9 +1,9 @@ -- Add up migration script here CREATE TABLE modelle ( - id SERIAL PRIMARY KEY, + modell_id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, typ_id SERIAL, hersteller_id SERIAL, - CONSTRAINT fk_typ FOREIGN KEY(typ_id) REFERENCES typen(id), - CONSTRAINT fk_hersteller FOREIGN KEY (hersteller_id) REFERENCES hersteller(id) + CONSTRAINT fk_typ FOREIGN KEY(typ_id) REFERENCES typen(typ_id), + CONSTRAINT fk_hersteller FOREIGN KEY (hersteller_id) REFERENCES hersteller(hersteller_id) ) diff --git a/src/main.rs b/src/main.rs index ecddce2..87684bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,8 @@ async fn main() -> Result<()> { .data(db_pool) .finish(); + // println!("{}", &schema.sdl()); + let app = Router::new() .route("/ping", get(ping)) .route("/", get(graphiql).post_service(GraphQL::new(schema))); diff --git a/src/models/hersteller.rs b/src/models/hersteller.rs index 772a755..cb56bc7 100644 --- a/src/models/hersteller.rs +++ b/src/models/hersteller.rs @@ -3,10 +3,10 @@ use async_graphql::SimpleObject; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, PgPool}; -#[derive(SimpleObject, FromRow, Deserialize, Serialize)] +#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, sqlx::Type)] pub struct Hersteller { /// Die Datenbank-ID - pub id: i32, + pub hersteller_id: i32, /// Der Name eines Herstellers name: String, @@ -15,28 +15,32 @@ pub struct Hersteller { impl Hersteller { pub async fn create(pool: &PgPool, name: &str) -> Result { let row = sqlx::query!( - "INSERT INTO hersteller(name) VALUES ($1) RETURNING id", + "INSERT INTO hersteller(name) VALUES ($1) RETURNING hersteller_id", name ) .fetch_one(pool) .await?; Ok(Hersteller { - id: row.id, + hersteller_id: row.hersteller_id, name: name.to_string(), }) } pub async fn read_one(pool: &PgPool, id: &i32) -> Result { - let row = sqlx::query_as!(Hersteller, "SELECT * FROM hersteller WHERE id = $1", id) - .fetch_one(pool) - .await?; + let row = sqlx::query_as!( + Hersteller, + "SELECT * FROM hersteller WHERE hersteller_id = $1", + id + ) + .fetch_one(pool) + .await?; Ok(row) } pub async fn read_all(pool: &PgPool) -> Result> { - let rows = sqlx::query_as!(Hersteller, "SELECT id, name FROM hersteller") + let rows = sqlx::query_as!(Hersteller, "SELECT hersteller_id, name FROM hersteller") .fetch_all(pool) .await?; @@ -44,9 +48,13 @@ impl Hersteller { } pub async fn update(pool: &PgPool, id: &i32, name: &str) -> Result { - sqlx::query!("UPDATE hersteller SET name=$1 WHERE id = $2", name, id) - .execute(pool) - .await?; + sqlx::query!( + "UPDATE hersteller SET name=$1 WHERE hersteller_id = $2", + name, + id + ) + .execute(pool) + .await?; let t = Hersteller::read_one(pool, id).await?; @@ -54,7 +62,7 @@ impl Hersteller { } pub async fn delete(pool: &PgPool, id: &i32) -> Result<()> { - sqlx::query!("DELETE FROM hersteller WHERE id = $1", id) + sqlx::query!("DELETE FROM hersteller WHERE hersteller_id = $1", id) .execute(pool) .await?; diff --git a/src/models/mod.rs b/src/models/mod.rs index 5a3235d..da6ad95 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,3 +1,4 @@ pub mod hersteller; pub mod modell; +pub mod modell_temp; pub mod typ; diff --git a/src/models/modell.rs b/src/models/modell.rs index 3534d42..fd0a4dd 100644 --- a/src/models/modell.rs +++ b/src/models/modell.rs @@ -6,7 +6,7 @@ use sqlx::{FromRow, PgPool}; #[derive(SimpleObject, FromRow, Deserialize, Serialize)] pub struct Modell { /// Die Datenbank-ID - pub id: i32, + pub modell_id: i32, /// Der Typ typ_id: i32, @@ -14,10 +14,7 @@ pub struct Modell { /// Der Hersteller hersteller_id: i32, - /** - * Der Name eines Modells - * Das ist ein Zusatz - */ + /// Der Name eines Modells name: String, } @@ -29,7 +26,7 @@ impl Modell { name: &str, ) -> Result { let row = sqlx::query!( - "INSERT INTO modelle(typ_id, hersteller_id, name) VALUES ($1, $2, $3) RETURNING id", + "INSERT INTO modelle(typ_id, hersteller_id, name) VALUES ($1, $2, $3) RETURNING modell_id", typ_id, hersteller_id, name @@ -38,7 +35,7 @@ impl Modell { .await?; Ok(Modell { - id: row.id, + modell_id: row.modell_id, typ_id, hersteller_id, name: name.to_string(), @@ -46,7 +43,7 @@ impl Modell { } pub async fn read_one(pool: &PgPool, id: &i32) -> Result { - let row = sqlx::query_as!(Modell, "SELECT * FROM modelle WHERE id = $1", id) + let row = sqlx::query_as!(Modell, "SELECT * FROM modelle WHERE modell_id = $1", id) .fetch_one(pool) .await?; @@ -56,7 +53,7 @@ impl Modell { pub async fn read_all(pool: &PgPool) -> Result> { let rows = sqlx::query_as!( Modell, - "SELECT id, name, hersteller_id, typ_id FROM modelle" + "SELECT modell_id, name, hersteller_id, typ_id FROM modelle" ) .fetch_all(pool) .await?; @@ -64,28 +61,8 @@ impl Modell { Ok(rows) } - pub async fn read_by_typ(pool: &PgPool, typ_id: &i32) -> Result> { - let row = sqlx::query_as!(Modell, "SELECT * FROM modelle WHERE typ_id = $1", typ_id) - .fetch_all(pool) - .await?; - - Ok(row) - } - - pub async fn read_by_hersteller(pool: &PgPool, hersteller_id: &i32) -> Result> { - let row = sqlx::query_as!( - Modell, - "SELECT * FROM modelle WHERE hersteller_id = $1", - hersteller_id - ) - .fetch_all(pool) - .await?; - - Ok(row) - } - pub async fn update(pool: &PgPool, id: &i32, name: &str) -> Result { - sqlx::query!("UPDATE modelle SET name=$1 WHERE id = $2", name, id) + sqlx::query!("UPDATE modelle SET name=$1 WHERE modell_id = $2", name, id) .execute(pool) .await?; @@ -95,7 +72,7 @@ impl Modell { } pub async fn delete(pool: &PgPool, id: &i32) -> Result<()> { - sqlx::query!("DELETE FROM modelle WHERE id = $1", id) + sqlx::query!("DELETE FROM modelle WHERE modell_id = $1", id) .execute(pool) .await?; diff --git a/src/models/modell_temp.rs b/src/models/modell_temp.rs new file mode 100644 index 0000000..b73365f --- /dev/null +++ b/src/models/modell_temp.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use async_graphql::SimpleObject; +use serde::{Deserialize, Serialize}; +use sqlx::{FromRow, PgPool}; + +use super::{hersteller::Hersteller, typ::Typ}; + +#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize)] +pub struct ModellTemp { + /// Die Datenbank-ID + pub modell_id: i32, + + /// Der Typ + pub typ: Typ, + + /// Der Hersteller + pub hersteller: Hersteller, + + /// Der Name eines Modells + pub name: String, +} + +impl ModellTemp { + pub async fn read_one(pool: &PgPool, id: &i32) -> Result { + let row = sqlx::query_as!( + ModellTemp, + r#" + select + m.modell_id, m.name, + (t.typ_id, t.name) as "typ!: Typ", + (h.hersteller_id, h.name) as "hersteller!: Hersteller" + from modelle as m + join typen as t using(typ_id) + join hersteller as h using(hersteller_id) + where m.modell_id = $1; + "#, + id + ) + .fetch_one(pool) + .await?; + + Ok(row) + } +} diff --git a/src/models/typ.rs b/src/models/typ.rs index 63150b3..bef13c9 100644 --- a/src/models/typ.rs +++ b/src/models/typ.rs @@ -1,31 +1,30 @@ use anyhow::Result; use async_graphql::SimpleObject; use serde::{Deserialize, Serialize}; -use sqlx::{FromRow, PgPool}; +use sqlx::{FromRow, PgPool, Type}; -#[derive(SimpleObject, FromRow, Deserialize, Serialize)] +#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, Type)] pub struct Typ { - /// Die Datenbank-ID - pub id: i32, + pub typ_id: i32, /// Der Name eines Typs - name: String, + pub name: String, } impl Typ { pub async fn create(pool: &PgPool, name: &str) -> Result { - let row = sqlx::query!("INSERT INTO typen(name) VALUES ($1) RETURNING id", name) + let row = sqlx::query!("INSERT INTO typen(name) VALUES ($1) RETURNING typ_id", name) .fetch_one(pool) .await?; Ok(Typ { - id: row.id, + typ_id: row.typ_id, name: name.to_string(), }) } pub async fn read_one(pool: &PgPool, id: &i32) -> Result { - let row = sqlx::query_as!(Typ, "SELECT * FROM typen WHERE id = $1", id) + let row = sqlx::query_as!(Typ, "SELECT * FROM typen WHERE typ_id = $1", id) .fetch_one(pool) .await?; @@ -33,7 +32,7 @@ impl Typ { } pub async fn read_all(pool: &PgPool) -> Result> { - let rows = sqlx::query_as!(Typ, "SELECT id, name FROM typen") + let rows = sqlx::query_as!(Typ, "SELECT typ_id, name FROM typen") .fetch_all(pool) .await?; @@ -41,7 +40,7 @@ impl Typ { } pub async fn update(pool: &PgPool, id: &i32, name: &str) -> Result { - sqlx::query!("UPDATE typen SET name=$1 WHERE id = $2", name, id) + sqlx::query!("UPDATE typen SET name=$1 WHERE typ_id = $2", name, id) .execute(pool) .await?; @@ -51,7 +50,7 @@ impl Typ { } pub async fn delete(pool: &PgPool, id: &i32) -> Result<()> { - sqlx::query!("DELETE FROM typen WHERE id = $1", id) + sqlx::query!("DELETE FROM typen WHERE typ_id = $1", id) .execute(pool) .await?; diff --git a/src/queries/mod.rs b/src/queries/mod.rs index 1703ea0..1bbb38c 100644 --- a/src/queries/mod.rs +++ b/src/queries/mod.rs @@ -1,5 +1,6 @@ pub mod hersteller; pub mod modell; +pub mod modell_temp; pub mod typ; use async_graphql::MergedObject; @@ -8,5 +9,6 @@ use async_graphql::MergedObject; pub struct Query( typ::TypQuery, modell::ModellQuery, + modell_temp::ModellTempQuery, hersteller::HerstellerQuery, ); diff --git a/src/queries/modell_temp.rs b/src/queries/modell_temp.rs new file mode 100644 index 0000000..5aec0a1 --- /dev/null +++ b/src/queries/modell_temp.rs @@ -0,0 +1,22 @@ +use async_graphql::{Context, FieldResult, Object}; +use sqlx::postgres::PgPool; + +use crate::models::modell_temp::ModellTemp; + +#[derive(Default)] +pub struct ModellTempQuery {} + +#[Object(extends)] +impl ModellTempQuery { + // async fn modelle<'a>(&self, ctx: &'a Context<'_>) -> FieldResult> { + // let pool = ctx.data::()?; + // let rows = ModellTemp::read_all(pool).await?; + // Ok(rows) + // } + + async fn modell_temp<'a>(&self, ctx: &'a Context<'_>, id: i32) -> FieldResult { + let pool = ctx.data::()?; + let row = ModellTemp::read_one(pool, &id).await?; + Ok(row) + } +}