From e337d202ae305b43fc158597c67cbe751cc7a722 Mon Sep 17 00:00:00 2001 From: Peter Schiwy Date: Mon, 3 Feb 2025 22:32:05 +0100 Subject: [PATCH] first commit --- Cargo.toml | 7 ++ database/.gitignore | 1 + database/Cargo.toml | 6 + database/src/lib.rs | 18 +++ main/.gitignore | 1 + main/Cargo.toml | 7 ++ main/src/main.rs | 10 ++ migration/Cargo.toml | 21 ++++ migration/README.md | 41 +++++++ migration/src/lib.rs | 16 +++ migration/src/m20250202_000233_benutzer.rs | 78 +++++++++++++ migration/src/m20250202_225521_hardware.rs | 125 +++++++++++++++++++++ migration/src/main.rs | 6 + 13 files changed, 337 insertions(+) create mode 100644 Cargo.toml create mode 100644 database/.gitignore create mode 100644 database/Cargo.toml create mode 100644 database/src/lib.rs create mode 100644 main/.gitignore create mode 100644 main/Cargo.toml create mode 100644 main/src/main.rs create mode 100644 migration/Cargo.toml create mode 100644 migration/README.md create mode 100644 migration/src/lib.rs create mode 100644 migration/src/m20250202_000233_benutzer.rs create mode 100644 migration/src/m20250202_225521_hardware.rs create mode 100644 migration/src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0c6106d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +resolver = "3" + +members = ["migration", "database", "main"] + +[env] +DATABASE_URL = "postgres://peter:peter@192.168.188.249:5432/web-test" diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +/target diff --git a/database/Cargo.toml b/database/Cargo.toml new file mode 100644 index 0000000..407f7da --- /dev/null +++ b/database/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "database" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/database/src/lib.rs b/database/src/lib.rs new file mode 100644 index 0000000..1777d0b --- /dev/null +++ b/database/src/lib.rs @@ -0,0 +1,18 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +pub fn sub(left: u64, right: u64) -> u64 { + left - right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/main/.gitignore b/main/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/main/.gitignore @@ -0,0 +1 @@ +/target diff --git a/main/Cargo.toml b/main/Cargo.toml new file mode 100644 index 0000000..2249043 --- /dev/null +++ b/main/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "main" +version = "0.1.0" +edition = "2021" + +[dependencies] +database = { path = "../database" } diff --git a/main/src/main.rs b/main/src/main.rs new file mode 100644 index 0000000..20a5f81 --- /dev/null +++ b/main/src/main.rs @@ -0,0 +1,10 @@ +use database::add; +use database::sub; + +fn main() { + let test = add(2, 5); + let sub = sub(10, 5); + + println!("{test}"); + println!("{sub}"); +} diff --git a/migration/Cargo.toml b/migration/Cargo.toml new file mode 100644 index 0000000..e0a06dc --- /dev/null +++ b/migration/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "migration" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +async-std = { version = "1", features = ["attributes", "tokio1"] } +chrono = { version = "0.4", features = ["serde"] } + +[dependencies.sea-orm-migration] +version = "1.1.4" +features = [ + "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature + "sqlx-postgres", # `DATABASE_DRIVER` feature + "with-chrono", +] diff --git a/migration/README.md b/migration/README.md new file mode 100644 index 0000000..3b438d8 --- /dev/null +++ b/migration/README.md @@ -0,0 +1,41 @@ +# Running Migrator CLI + +- Generate a new migration file + ```sh + cargo run -- generate MIGRATION_NAME + ``` +- Apply all pending migrations + ```sh + cargo run + ``` + ```sh + cargo run -- up + ``` +- Apply first 10 pending migrations + ```sh + cargo run -- up -n 10 + ``` +- Rollback last applied migrations + ```sh + cargo run -- down + ``` +- Rollback last 10 applied migrations + ```sh + cargo run -- down -n 10 + ``` +- Drop all tables from the database, then reapply all migrations + ```sh + cargo run -- fresh + ``` +- Rollback all applied migrations, then reapply all migrations + ```sh + cargo run -- refresh + ``` +- Rollback all applied migrations + ```sh + cargo run -- reset + ``` +- Check the status of all migrations + ```sh + cargo run -- status + ``` diff --git a/migration/src/lib.rs b/migration/src/lib.rs new file mode 100644 index 0000000..65ee896 --- /dev/null +++ b/migration/src/lib.rs @@ -0,0 +1,16 @@ +pub use sea_orm_migration::prelude::*; + +mod m20250202_000233_benutzer; +mod m20250202_225521_hardware; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![ + Box::new(m20250202_000233_benutzer::Migration), + Box::new(m20250202_225521_hardware::Migration), + ] + } +} diff --git a/migration/src/m20250202_000233_benutzer.rs b/migration/src/m20250202_000233_benutzer.rs new file mode 100644 index 0000000..21fd1e4 --- /dev/null +++ b/migration/src/m20250202_000233_benutzer.rs @@ -0,0 +1,78 @@ +use chrono::Utc; +use sea_orm_migration::{prelude::*, schema::*}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Benutzer::Table) + .if_not_exists() + .col(pk_uuid(Benutzer::Id)) + .col(string(Benutzer::EMail)) + .col(string(Benutzer::Kennung)) + .col(string(Benutzer::PasswordHash)) + .col(string(Benutzer::Nachname)) + .col(string(Benutzer::Vorname)) + .col( + timestamp_with_time_zone(Benutzer::ErstelltAm) + .not_null() + .default(Utc::now()), + ) + .col( + timestamp_with_time_zone(Benutzer::GeaendertAm) + .not_null() + .default(Utc::now()), + ) + .col(boolean(Benutzer::IstAktiv)) + .to_owned(), + ) + .await?; + + manager + .create_index( + Index::create() + .unique() + .name("idx_benutzer_email") + .table(Benutzer::Table) + .col(Benutzer::EMail) + .to_owned(), + ) + .await?; + + manager + .create_index( + Index::create() + .unique() + .name("idx_benutzer_kennung") + .table(Benutzer::Table) + .col(Benutzer::Kennung) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Benutzer::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Benutzer { + Table, + Id, + EMail, + Kennung, + PasswordHash, + Nachname, + Vorname, + ErstelltAm, + GeaendertAm, + IstAktiv, +} diff --git a/migration/src/m20250202_225521_hardware.rs b/migration/src/m20250202_225521_hardware.rs new file mode 100644 index 0000000..1970400 --- /dev/null +++ b/migration/src/m20250202_225521_hardware.rs @@ -0,0 +1,125 @@ +use chrono::Utc; +use extension::postgres::Type; +use sea_orm::{EnumIter, Iterable}; +use sea_orm_migration::{prelude::*, schema::*}; + +use crate::m20250202_000233_benutzer::Benutzer; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[derive(DeriveIden)] +#[sea_orm(iden = "status_type_enum")] +struct StatusTypeEnum; + +#[derive(DeriveIden, EnumIter)] +pub enum StatusVarianten { + #[sea_orm(iden = "verfuegbar", string_value = "Verfügbar")] + Verfuegbar, + #[sea_orm(iden = "in_benutzung", string_value = "In Benutzung")] + InBenutzung, + #[sea_orm(iden = "in_wartung", string_value = "In Wartung")] + InWartung, + #[sea_orm(iden = "in_reparatur", string_value = "In Reparatur")] + InReparatur, + #[sea_orm(iden = "verloren", string_value = "Verloren")] + Verloren, + #[sea_orm(iden = "defekt", string_value = "Defekt")] + Defekt, + #[sea_orm(iden = "re_invest", string_value = "ReInvest")] + ReInvest, +} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_type( + Type::create() + .as_enum(StatusTypeEnum) + .values(StatusVarianten::iter()) + .to_owned(), + ) + .await?; + + manager + .create_table( + Table::create() + .table(Hardware::Table) + .if_not_exists() + .col(pk_uuid(Hardware::Id)) + .col(string(Hardware::Name)) + .col(string(Hardware::Seriennummer)) + .col(text(Hardware::Beschreibung)) + .col(enumeration( + Hardware::Status, + StatusTypeEnum, + StatusVarianten::iter(), + )) + .col(uuid(Hardware::BenutzerId)) + .col( + timestamp_with_time_zone(Hardware::ErstelltAm) + .not_null() + .default(Utc::now()), + ) + .col( + timestamp_with_time_zone(Hardware::GeaendertAm) + .not_null() + .default(Utc::now()), + ) + .foreign_key( + ForeignKey::create() + .name("fk_hardware_benutzer") + .from(Hardware::Table, Hardware::BenutzerId) + .to(Benutzer::Table, Benutzer::Id), + ) + .to_owned(), + ) + .await?; + + manager + .create_index( + Index::create() + .unique() + .name("idx_hardware_seriennummer") + .table(Hardware::Table) + .col(Hardware::Seriennummer) + .to_owned(), + ) + .await?; + + manager + .create_index( + Index::create() + .unique() + .name("idx_hardware_benuzter_id") + .table(Hardware::Table) + .col(Hardware::BenutzerId) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Hardware::Table).to_owned()) + .await?; + + manager + .drop_type(Type::drop().name(StatusTypeEnum).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +enum Hardware { + Table, + Id, + Name, + Seriennummer, + Beschreibung, + Status, + BenutzerId, + ErstelltAm, + GeaendertAm, +} diff --git a/migration/src/main.rs b/migration/src/main.rs new file mode 100644 index 0000000..c6b6e48 --- /dev/null +++ b/migration/src/main.rs @@ -0,0 +1,6 @@ +use sea_orm_migration::prelude::*; + +#[async_std::main] +async fn main() { + cli::run_cli(migration::Migrator).await; +}