Die Tabellen Benutzer, Rollen und Gruppen hinzugefügt

This commit is contained in:
Peter Schiwy 2024-11-29 10:35:10 +01:00
parent a290bcceb3
commit fdc57ab13a
48 changed files with 771 additions and 267 deletions

347
Cargo.lock generated
View File

@ -34,7 +34,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
@ -127,9 +126,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "async-graphql"
version = "7.0.6"
version = "7.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf338d20ba5bab309f55ce8df95d65ee19446f7737f06f4a64593ab2c6b546ad"
checksum = "0ba6d24703c5adc5ba9116901b92ee4e4c0643c01a56c4fd303f3818638d7449"
dependencies = [
"async-graphql-derive",
"async-graphql-parser",
@ -163,9 +162,9 @@ dependencies = [
[[package]]
name = "async-graphql-axum"
version = "7.0.6"
version = "7.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28f874ad4bc10519f3fa500e36814452033a5ce9ea681ab0a2e0d3b1f18bae44"
checksum = "e9aa80e171205c6d562057fd5a49167c8fbe61f7db2bed6540f6d4f2234d7ff2"
dependencies = [
"async-graphql",
"async-trait",
@ -181,9 +180,9 @@ dependencies = [
[[package]]
name = "async-graphql-derive"
version = "7.0.6"
version = "7.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc51fd6b7102acda72bc94e8ae1543844d5688ff394a6cf7c21f2a07fe2d64e4"
checksum = "a94c2d176893486bd37cd1b6defadd999f7357bf5804e92f510c08bcf16c538f"
dependencies = [
"Inflector",
"async-graphql-parser",
@ -192,15 +191,15 @@ dependencies = [
"proc-macro2",
"quote",
"strum",
"syn 2.0.66",
"syn",
"thiserror",
]
[[package]]
name = "async-graphql-parser"
version = "7.0.6"
version = "7.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75361eefd64e39f89bead4cb45fddbaf60ddb0e7b15fb7c852b6088bcd63071f"
checksum = "79272bdbf26af97866e149f05b2b546edb5c00e51b5f916289931ed233e208ad"
dependencies = [
"async-graphql-value",
"pest",
@ -210,9 +209,9 @@ dependencies = [
[[package]]
name = "async-graphql-value"
version = "7.0.6"
version = "7.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1f665d2d52b41c4ed1f01c43f3ef27a2fe0af2452ed5c8bc7ac9b1a8719afaa"
checksum = "ef5ec94176a12a8cbe985cd73f2e54dc9c702c88c766bdef12f1f3a67cedbee1"
dependencies = [
"bytes",
"indexmap",
@ -239,7 +238,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -250,7 +249,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -323,6 +322,7 @@ dependencies = [
"sqlx",
"tokio",
"tracing",
"tracing-appender",
"tracing-subscriber",
"ulid",
"uuid",
@ -355,10 +355,10 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
dependencies = [
"heck",
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -441,9 +441,12 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.98"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
@ -472,6 +475,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-oid"
version = "0.9.6"
@ -518,6 +530,15 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crossbeam-channel"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
@ -545,9 +566,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
@ -555,27 +576,27 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.66",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -595,6 +616,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]]
name = "digest"
version = "0.10.7"
@ -649,9 +679,9 @@ dependencies = [
[[package]]
name = "env_logger"
version = "0.11.3"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
checksum = "06676b12debf7bba6903559720abca942d3a66b8acb88815fd2c7c6537e9ade1"
dependencies = [
"anstream",
"anstyle",
@ -698,9 +728,14 @@ dependencies = [
[[package]]
name = "event-listener"
version = "2.5.3"
version = "5.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "fastrand"
@ -801,7 +836,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -894,9 +929,9 @@ dependencies = [
[[package]]
name = "hashlink"
version = "0.8.4"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
dependencies = [
"hashbrown",
]
@ -906,9 +941,12 @@ name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
@ -1138,9 +1176,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libsqlite3-sys"
version = "0.27.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
dependencies = [
"cc",
"pkg-config",
@ -1165,9 +1203,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "lru"
@ -1232,13 +1270,14 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.11"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
dependencies = [
"hermit-abi",
"libc",
"wasi",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@ -1313,6 +1352,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.46"
@ -1343,16 +1388,6 @@ dependencies = [
"libm",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "object"
version = "0.32.2"
@ -1391,7 +1426,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -1418,6 +1453,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -1464,9 +1505,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.10"
version = "2.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8"
checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442"
dependencies = [
"memchr",
"thiserror",
@ -1493,7 +1534,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -1524,7 +1565,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -1566,6 +1607,12 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1583,9 +1630,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.84"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
@ -1782,22 +1829,22 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.203"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.203"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -1864,6 +1911,12 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signature"
version = "2.2.0"
@ -1888,6 +1941,9 @@ name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
dependencies = [
"serde",
]
[[package]]
name = "socket2"
@ -1937,9 +1993,9 @@ dependencies = [
[[package]]
name = "sqlx"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e"
dependencies = [
"sqlx-core",
"sqlx-macros",
@ -1950,11 +2006,10 @@ dependencies = [
[[package]]
name = "sqlx-core"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e"
dependencies = [
"ahash",
"atoi",
"byteorder",
"bytes",
@ -1968,6 +2023,7 @@ dependencies = [
"futures-intrusive",
"futures-io",
"futures-util",
"hashbrown",
"hashlink",
"hex",
"indexmap",
@ -1992,26 +2048,26 @@ dependencies = [
[[package]]
name = "sqlx-macros"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127"
checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 1.0.109",
"syn",
]
[[package]]
name = "sqlx-macros-core"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
dependencies = [
"dotenvy",
"either",
"heck",
"heck 0.5.0",
"hex",
"once_cell",
"proc-macro2",
@ -2023,7 +2079,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109",
"syn",
"tempfile",
"tokio",
"url",
@ -2031,12 +2087,12 @@ dependencies = [
[[package]]
name = "sqlx-mysql"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a"
dependencies = [
"atoi",
"base64 0.21.7",
"base64 0.22.1",
"bitflags 2.5.0",
"byteorder",
"bytes",
@ -2075,12 +2131,12 @@ dependencies = [
[[package]]
name = "sqlx-postgres"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8"
dependencies = [
"atoi",
"base64 0.21.7",
"base64 0.22.1",
"bitflags 2.5.0",
"byteorder",
"chrono",
@ -2115,9 +2171,9 @@ dependencies = [
[[package]]
name = "sqlx-sqlite"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
dependencies = [
"atoi",
"chrono",
@ -2131,10 +2187,10 @@ dependencies = [
"log",
"percent-encoding",
"serde",
"serde_urlencoded",
"sqlx-core",
"tracing",
"url",
"urlencoding",
"uuid",
]
@ -2176,11 +2232,11 @@ version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
dependencies = [
"heck",
"heck 0.4.1",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.66",
"syn",
]
[[package]]
@ -2191,20 +2247,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "1.0.109"
version = "2.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
dependencies = [
"proc-macro2",
"quote",
@ -2252,7 +2297,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -2265,6 +2310,37 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -2282,30 +2358,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.38.0"
version = "1.39.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
@ -2392,9 +2467,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.40"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"log",
"pin-project-lite",
@ -2403,21 +2478,33 @@ dependencies = [
]
[[package]]
name = "tracing-attributes"
version = "0.1.27"
name = "tracing-appender"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
dependencies = [
"crossbeam-channel",
"thiserror",
"time",
"tracing-subscriber",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
"valuable",
@ -2486,9 +2573,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
[[package]]
name = "ulid"
version = "1.1.2"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34778c17965aa2a08913b57e1f34db9b4a63f5de31768b55bf20d2795f921259"
checksum = "04f903f293d11f31c0c29e4148f6dc0d033a7f80cebc0282bea147611667d289"
dependencies = [
"getrandom",
"rand",
@ -2523,12 +2610,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode_categories"
version = "0.1.1"
@ -2546,12 +2627,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf-8"
version = "0.7.6"
@ -2566,9 +2641,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.8.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"getrandom",
"serde",
@ -2625,7 +2700,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
"wasm-bindgen-shared",
]
@ -2647,7 +2722,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -2874,7 +2949,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
"syn",
]
[[package]]

View File

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
async-graphql = { version = "7.0.5", default-features = false, features = [
async-graphql = { version = "7.0.11", default-features = false, features = [
"chrono",
"uuid",
'dataloader',
@ -13,7 +13,7 @@ async-graphql = { version = "7.0.5", default-features = false, features = [
'playground',
] }
axum = { version = "0.7.5", features = ["macros"] }
sqlx = { version = "0.7.4", features = [
sqlx = { version = "0.8.2", features = [
"runtime-tokio-native-tls",
"uuid",
"postgres",
@ -21,19 +21,20 @@ sqlx = { version = "0.7.4", features = [
"macros",
] }
anyhow = "1.0.86"
async-graphql-axum = "7.0.6"
async-graphql-axum = "7.0.11"
chrono = { version = "0.4.38", features = ["serde"] }
dotenv = "0.15.0"
envy = "0.4.2"
env_logger = "0.11.3"
log = "0.4.21"
serde = "1.0.203"
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] }
env_logger = "0.11.4"
log = "0.4.22"
serde = "1.0.215"
tokio = { version = "1.39.1", features = ["macros", "rt-multi-thread"] }
# UUID
uuid = { version = "1.8.0", features = ["serde", "v4"] }
ulid = { version = "1.1.2", features = ["uuid"] }
uuid = { version = "1.11.0", features = ["serde", "v4"] }
ulid = { version = "1.1.3", features = ["uuid"] }
# Logging
tracing = "0.1.40"
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "chrono"] }
tracing-appender = "0.2.3"

5
build.rs Normal file
View File

@ -0,0 +1,5 @@
// generated by `sqlx migrate build-script`
fn main() {
// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
}

View File

@ -1,2 +1 @@
-- Add down migration script here
DROP TABLE typen;

View File

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

View File

@ -1,2 +1 @@
-- Add down migration script here
DROP TABLE hersteller;

View File

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

View File

@ -1,2 +1 @@
-- Add down migration script here
DROP TABLE modelle;

View File

@ -1,9 +1,16 @@
-- Add up migration script here
CREATE TABLE IF NOT EXISTS modelle (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
typ_id SERIAL,
hersteller_id SERIAL,
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(id) ON DELETE NO ACTION ON UPDATE NO ACTION
id UUID PRIMARY KEY,
modellname VARCHAR NOT NULL,
typ_id UUID,
hersteller_id UUID,
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 (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)

View File

@ -0,0 +1 @@
DROP TABLE gruppen;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS gruppen (
id UUID PRIMARY KEY,
gruppenname VARCHAR NOT NULL,
erstellt_am TIMESTAMP WITH TIME ZONE NOT NULL,
geaendert_am TIMESTAMP WITH TIME ZONE NOT NULL
)

View File

@ -0,0 +1 @@
DROP TABLE rollen;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS rollen (
id UUID PRIMARY KEY,
rollenname VARCHAR NOT NULL,
erstellt_am TIMESTAMP WITH TIME ZONE NOT NULL,
geaendert_am TIMESTAMP WITH TIME ZONE NOT NULL
)

View File

@ -0,0 +1 @@
DROP TABLE rollen_gruppen;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS rollen_gruppen (
rolle_id UUID NOT NULL,
gruppe_id UUID NOT NULL,
CONSTRAINT pk_rollen_gruppen PRIMARY KEY (rolle_id, gruppe_id),
CONSTRAINT fk_rollen_gruppen_gruppe FOREIGN KEY (gruppe_id)
REFERENCES gruppen (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_rollen_gruppen_rolle FOREIGN KEY (rolle_id)
REFERENCES rollen (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
)

View File

@ -0,0 +1 @@
DROP TABLE benutzer;

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS benutzer (
id UUID PRIMARY KEY,
kennung VARCHAR NOT NULL,
nachname VARCHAR NOT NULL,
vorname VARCHAR NOT NULL
)

View File

@ -0,0 +1 @@
DROP TABLE benutzer_gruppen;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS benutzer_gruppen (
benutzer_id UUID NOT NULL,
gruppe_id UUID NOT NULL,
CONSTRAINT pk_benutzer_gruppen PRIMARY KEY (benutzer_id, gruppe_id),
CONSTRAINT fk_benutzer_gruppen_benutzer FOREIGN KEY (benutzer_id)
REFERENCES benutzer (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_benutzer_gruppen_gruppe FOREIGN KEY (gruppe_id)
REFERENCES gruppen (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
)

View File

@ -0,0 +1 @@
DROP TABLE benutzer_rollen;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS benutzer_rollen (
benutzer_id UUID NOT NULL,
rolle_id UUID NOT NULL,
CONSTRAINT pk_benutzer_rollen PRIMARY KEY (benutzer_id, rolle_id),
CONSTRAINT fk_benutzer_rollen_benutzer FOREIGN KEY (benutzer_id)
REFERENCES benutzer (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_benutzer_rollen_rolle FOREIGN KEY (rolle_id)
REFERENCES rollen (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
)

View File

@ -5,5 +5,5 @@ pub struct Rolle {
pub id: Id,
pub created_at: Time,
pub updated_at: Time,
pub name: String,
pub rollenname: String,
}

View File

@ -2,5 +2,6 @@ mod rolle;
mod rolle_create_input;
mod rolle_update_input;
pub use rolle::Gruppe;
pub use rolle::Rolle;
pub use rolle_create_input::RolleCreateInput;

View File

@ -2,17 +2,35 @@ use async_graphql::SimpleObject;
use crate::scalar::{Id, Time};
#[derive(Debug, SimpleObject)]
#[derive(Debug, SimpleObject, sqlx::FromRow)]
pub struct Rolle {
/// Die ID einer Rolle
pub id: Id,
/// Wann die Rolle erstellt wurde
/// Zeit wann die Rolle erstellt wurde
pub created_at: Time,
/// Wann die Rolle geändert wurde
/// Zeit wann die Rolle geändert wurde
pub updated_at: Time,
/// Der Name einer Rolle
pub name: String,
pub rollenname: String,
pub gruppen: Vec<Gruppe>,
}
/// TODO: Migration in ein separates Modul
#[derive(Debug, SimpleObject, sqlx::Type)]
pub struct Gruppe {
/// Die ID einer Gruppe
pub id: Id,
/// Zeit wann die Gruppe erstellt wurde
pub created_at: Time,
///Zeit wann die Gruppe geändert wurde
pub updated_at: Time,
/// Der Name einer Gruppe
pub gruppenname: String,
}

View File

@ -3,5 +3,5 @@ use async_graphql::InputObject;
#[derive(InputObject)]
pub struct RolleCreateInput {
/// Der Name einer Rolle
pub name: String,
pub rollenname: String,
}

View File

@ -8,5 +8,5 @@ pub struct RolleUpdateInput {
pub id: Id,
/// Der Name einer Rolle
pub name: String,
pub rollenname: String,
}

View File

@ -1,23 +1,24 @@
use anyhow::Error;
use super::Repository;
// use crate::domain::rolle::model;
use crate::{database::Queryer, domain::rolle::entity};
use crate::database::Queryer;
use crate::domain::rolle::entity;
use crate::scalar::Id;
impl Repository {
pub async fn create_rolle<'c, C: Queryer<'c>>(
&self,
db: C,
rolle: &entity::Rolle,
) -> Result<entity::Rolle, Error> {
) -> Result<Id, Error> {
const QUERY: &str = "insert into rolle (id, created_at, updated_at,
name) values ($1, $2, $3, $4) returning *";
name) values ($1, $2, $3, $4) returning id";
match sqlx::query_as::<_, entity::Rolle>(QUERY)
match sqlx::query_scalar::<_, Id>(QUERY)
.bind(rolle.id)
.bind(rolle.created_at)
.bind(rolle.updated_at)
.bind(&rolle.name)
.bind(&rolle.rollenname)
.fetch_one(db)
.await
{
@ -25,7 +26,7 @@ impl Repository {
tracing::error!("{}", &err);
Err(err.into())
}
Ok(user) => Ok(user),
Ok(id) => Ok(id),
}
}
}

View File

@ -0,0 +1,47 @@
use anyhow::Error;
use super::Repository;
use crate::database::Queryer;
use crate::domain::rolle::model::{self};
use crate::scalar::Id;
impl Repository {
pub async fn find_rolle_by_id<'c, C: Queryer<'c>>(
&self,
db: C,
id: Id,
) -> Result<model::Rolle, Error> {
const QUERY: &str = r#"
select
r.id, r.created_at, r.updated_at, r.rollenname,
(g.id, g.created_at, g.updated_at, g.gruppenname) as "gruppen!: Vec<model::Gruppe>"
from rollen as r
join rollen_gruppen as rg on rg.rolle_id = r.id
join gruppen as g on rg.gruppe_id = g.id
where r.id = $1;
"#;
let row = sqlx::query_as::<_, model::Rolle>(QUERY)
.bind(id)
.fetch_one(db)
.await?;
// let row = sqlx::query_as!(
// model::Rolle,
// r#"
// select
// r.id, r.created_at, r.updated_at, r.rollenname,
// (g.id, g.created_at, g.updated_at, g.gruppenname) as "gruppen!: Vec<model::Gruppe>"
// from rollen as r
// join rollen_gruppen as rg on rg.rolle_id = r.id
// join gruppen as g on rg.gruppe_id = g.id
// where r.id = $1;
// "#,
// id
// )
// .fetch_one(db)
// .await?;
Ok(row)
}
}

View File

@ -3,11 +3,11 @@ use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::rolle::entity;
use crate::domain::rolle::model::RolleCreateInput;
use crate::domain::rolle::{entity, model};
impl Service {
pub async fn create_rolle(&self, input: RolleCreateInput) -> Result<entity::Rolle, Error> {
pub async fn create_rolle(&self, input: RolleCreateInput) -> Result<model::Rolle, Error> {
// let username_exists = self.check_username_exists(&self.db, &input.name).await?;
// if username_exists {
// return Err(Error::UsernameAlreadyExists.into());
@ -15,12 +15,13 @@ impl Service {
let rolle_input = entity::Rolle {
id: Ulid::new().into(),
name: input.name,
rollenname: input.rollenname,
created_at: Utc::now(),
updated_at: Utc::now(),
};
let rolle = self.repo.create_rolle(&self.db, &rolle_input).await?;
let created_id = self.repo.create_rolle(&self.db, &rolle_input).await?;
let rolle = self.repo.find_rolle_by_id(&self.db, created_id).await?;
Ok(rolle)
}
}

8
src/format.sql Normal file
View File

@ -0,0 +1,8 @@
SELECT
g.id,
g.gruppenname,
g.erstellt_am,
g.geaendert_am
FROM gruppen AS g
LEFT JOIN rollen_gruppen AS rg ON g.id = rg.gruppe_id
WHERE rg.rolle_id = 1;

View File

@ -13,7 +13,7 @@ use dotenv::dotenv;
use mutations::Mutation;
use queries::Query;
use sqlx::postgres::PgPool;
use std::env;
use std::{env, sync::Arc};
use tokio::net::TcpListener;
mod config;
@ -38,13 +38,17 @@ async fn graphiql() -> impl IntoResponse {
#[tokio::main]
async fn main() -> Result<()> {
// tracing_subscriber::fmt()
// .with_max_level(tracing::Level::DEBUG)
// .init();
dotenv().ok();
env_logger::init();
Config::load();
// Config::load();
let config = Arc::new(Config::load()?);
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set");
let db_pool = PgPool::connect(&database_url).await?;
let db_pool = PgPool::connect(&config.database.url).await?;
let schema = Schema::build(Query::default(), Mutation::default(), EmptySubscription)
.data(db_pool)

78
src/models/benutzer.rs Normal file
View File

@ -0,0 +1,78 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::PgPool;
use crate::{models::gruppe::Gruppe, scalar::Id};
use super::rolle::Rolle;
pub struct Benutzer {
pub id: Id,
pub kennung: String,
pub vorname: String,
pub nachname: String,
}
#[Object]
impl Benutzer {
pub async fn id(&self) -> Id {
self.id
}
pub async fn kennung(&self) -> &str {
&self.kennung
}
pub async fn vorname(&self) -> &str {
&self.vorname
}
pub async fn nachname(&self) -> &str {
&self.nachname
}
pub async fn rollen<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Vec<Rolle>> {
let pool = ctx.data::<PgPool>()?;
let rows = sqlx::query_as!(
Rolle,
r#"
SELECT
r.id,
r.rollenname,
r.erstellt_am,
r.geaendert_am
FROM rollen AS r
LEFT JOIN benutzer_rollen AS br ON r.id = br.rolle_id
WHERE br.benutzer_id = $1;
"#,
&self.id
)
.fetch_all(pool)
.await?;
Ok(rows)
}
pub async fn gruppen<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Vec<Gruppe>> {
let pool = ctx.data::<PgPool>()?;
let rows = sqlx::query_as!(
Gruppe,
r#"
SELECT
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 = $1;
"#,
&self.id
)
.fetch_all(pool)
.await?;
Ok(rows)
}
}

30
src/models/gruppe.rs Normal file
View File

@ -0,0 +1,30 @@
use async_graphql::Object;
use crate::scalar::{Id, Time};
pub struct Gruppe {
pub id: Id,
pub gruppenname: String,
pub erstellt_am: Time,
pub geaendert_am: Time,
}
#[Object]
impl Gruppe {
pub async fn id(&self) -> Id {
self.id
}
pub async fn gruppenname(&self) -> &str {
&self.gruppenname
}
pub async fn erstellt_am(&self) -> Time {
self.erstellt_am
}
pub async fn geaendert_am(&self) -> Time {
self.geaendert_am
}
}

View File

@ -2,33 +2,36 @@ use anyhow::Result;
use async_graphql::{InputObject, SimpleObject};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, PgPool};
use ulid::Ulid;
use crate::scalar::Id;
#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, sqlx::Type)]
pub struct Hersteller {
/// Die Datenbank-ID
pub id: i32,
pub id: Id,
/// Der Name eines Herstellers
name: String,
herstellername: String,
}
#[derive(InputObject, Debug)]
pub struct HerstellerCreateInput {
/// Der Name eines Herstellers
pub name: String,
pub herstellername: String,
}
#[derive(InputObject, Debug)]
pub struct HerstellerUpdateInput {
/// Die Datenbank-ID
pub id: i32,
pub id: Id,
/// Der Name eines Herstellers
pub name: Option<String>,
pub herstellername: Option<String>,
}
impl Hersteller {
pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Hersteller> {
pub async fn read_one(pool: &PgPool, id: &Id) -> Result<Hersteller> {
let row = sqlx::query_as!(Hersteller, "SELECT * FROM hersteller WHERE id = $1", id)
.fetch_one(pool)
.await?;
@ -37,7 +40,7 @@ impl Hersteller {
}
pub async fn read_all(pool: &PgPool) -> Result<Vec<Hersteller>> {
let rows = sqlx::query_as!(Hersteller, "SELECT id, name FROM hersteller")
let rows = sqlx::query_as!(Hersteller, "SELECT id, herstellername FROM hersteller")
.fetch_all(pool)
.await?;
@ -45,21 +48,21 @@ impl Hersteller {
}
pub async fn create(pool: &PgPool, input: &HerstellerCreateInput) -> Result<Hersteller> {
let row = sqlx::query!(
"INSERT INTO hersteller(name) VALUES ($1) RETURNING id",
input.name
)
.fetch_one(pool)
.await?;
const QUERY: &str = "INSERT INTO hersteller (id, herstellername) VALUES ($1, $2) RETURNING id, herstellername";
let result: Hersteller = sqlx::query_as::<_, Hersteller>(QUERY)
.bind::<Id>(Ulid::new().into())
.bind(&input.herstellername)
.fetch_one(pool)
.await?;
let result = Self::read_one(pool, &row.id).await?;
Ok(result)
}
pub async fn update(pool: &PgPool, input: &HerstellerUpdateInput) -> Result<Hersteller> {
sqlx::query!(
"UPDATE hersteller SET name=$1 WHERE id = $2",
input.name,
"UPDATE hersteller SET herstellername=$1 WHERE id = $2",
input.herstellername,
input.id
)
.execute(pool)
@ -70,7 +73,7 @@ impl Hersteller {
Ok(t)
}
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
pub async fn delete(pool: &PgPool, id: &Id) -> Result<bool> {
let result = sqlx::query!("DELETE FROM hersteller WHERE id = $1", id)
.execute(pool)
.await?;

View File

@ -1,3 +1,6 @@
pub mod benutzer;
pub mod gruppe;
pub mod hersteller;
pub mod modell;
pub mod rolle;
pub mod typ;

View File

@ -2,13 +2,17 @@ use anyhow::Result;
use async_graphql::{InputObject, SimpleObject};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, PgPool};
use ulid::Ulid;
use uuid::Uuid;
use crate::scalar::Id;
use super::{hersteller::Hersteller, typ::Typ};
#[derive(SimpleObject, FromRow, Deserialize, Serialize, Debug)]
pub struct Modell {
/// Die Datenbank-ID
pub id: i32,
pub id: Id,
/// Der Geräte-Typ z.B. Monitor
typ: Typ,
@ -17,38 +21,44 @@ pub struct Modell {
hersteller: Hersteller,
/// Der Name eines Modells
name: String,
modellname: String,
}
#[derive(InputObject, Debug)]
pub struct ModellCreateInput {
pub name: String,
pub typ_id: i32,
pub hersteller_id: i32,
/// Der Name eines Modells
pub modellname: String,
/// Die Id eines Geräte-Typs z.B. Monitor
pub typ_id: Id,
/// Die Id eines Geräte-Herstellers z.B. Dell
pub hersteller_id: Id,
}
#[derive(InputObject, Debug)]
pub struct ModellUpdateInput {
pub id: i32,
pub name: Option<String>,
pub typ_id: Option<i32>,
pub hersteller_id: Option<i32>,
pub id: Id,
pub modellname: Option<String>,
pub typ_id: Option<Id>,
pub hersteller_id: Option<Id>,
}
impl Modell {
pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Modell> {
pub async fn read_one(pool: &PgPool, id: &Id) -> Result<Modell> {
let row = sqlx::query_as!(
Modell,
r#"
select
m.id, m.name,
(t.id, t.name) as "typ!: Typ",
(h.id, h.name) as "hersteller!: Hersteller"
from modelle as m
join typen as t on t.id = m.typ_id
join hersteller as h on h.id = m.hersteller_id
where m.id = $1;
"#,
SELECT
m.id,
m.modellname,
(t.id, t.typname) AS "typ!: Typ",
(h.id, h.herstellername) AS "hersteller!: Hersteller"
FROM modelle AS m
JOIN typen AS t ON t.id = m.typ_id
JOIN hersteller AS h ON h.id = m.hersteller_id
WHERE m.id = $1;
"#,
id
)
.fetch_one(pool)
@ -61,14 +71,15 @@ impl Modell {
let row = sqlx::query_as!(
Modell,
r#"
select
m.id, m.name,
(t.id, t.name) as "typ!: Typ",
(h.id, h.name) as "hersteller!: Hersteller"
from modelle as m
join typen as t on t.id = m.typ_id
join hersteller as h on h.id = m.hersteller_id
"#
SELECT
m.id,
m.modellname,
(t.id, t.typname) AS "typ!: Typ",
(h.id, h.herstellername) AS "hersteller!: Hersteller"
FROM modelle AS m
LEFT JOIN typen AS t ON t.id = m.typ_id
LEFT JOIN hersteller AS h ON h.id = m.hersteller_id
"#
)
.fetch_all(pool)
.await?;
@ -77,22 +88,25 @@ impl 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 id"#,
input.typ_id,
input.hersteller_id,
input.name
)
.fetch_one(pool)
.await?;
const QUERY: &str = "INSERT INTO modelle (id, typ_id, hersteller_id, modellname) VALUES ($1, $2, $3, $4) RETURNING id";
Self::read_one(pool, &row.id).await
let row: (Uuid,) = sqlx::query_as(QUERY)
.bind::<Id>(Ulid::new().into())
.bind(input.typ_id)
.bind(input.hersteller_id)
.bind(&input.modellname)
.fetch_one(pool)
.await?;
let modell = Modell::read_one(pool, &row.0).await?;
Ok(modell)
}
pub async fn update(pool: &PgPool, input: &ModellUpdateInput) -> Result<Modell> {
sqlx::query!(
"UPDATE modelle SET name=COALESCE($1, name), typ_id=COALESCE($2, typ_id), hersteller_id=COALESCE($3, hersteller_id) WHERE id = $4",
input.name,
"UPDATE modelle SET modellname=COALESCE($1, modellname), typ_id=COALESCE($2, typ_id), hersteller_id=COALESCE($3, hersteller_id) WHERE id = $4",
input.modellname,
input.typ_id,
input.hersteller_id,
input.id
@ -105,7 +119,7 @@ impl Modell {
Ok(t)
}
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
pub async fn delete(pool: &PgPool, id: &Id) -> Result<bool> {
let result = sqlx::query!("DELETE FROM modelle WHERE id = $1", id)
.execute(pool)
.await?;

57
src/models/rolle.rs Normal file
View File

@ -0,0 +1,57 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::PgPool;
use crate::scalar::{Id, Time};
use super::gruppe::Gruppe;
#[derive(Debug)]
pub struct Rolle {
pub id: Id,
pub rollenname: String,
pub erstellt_am: Time,
pub geaendert_am: Time,
}
#[Object]
impl Rolle {
pub async fn id(&self) -> Id {
self.id
}
pub async fn rollename(&self) -> &str {
&self.rollenname
}
pub async fn erstellt_am(&self) -> Time {
self.erstellt_am
}
pub async fn geaendert_am(&self) -> Time {
self.geaendert_am
}
pub async fn gruppen<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Vec<Gruppe>> {
let pool = ctx.data::<PgPool>()?;
let rows = sqlx::query_as!(
Gruppe,
r#"
SELECT
g.id,
g.gruppenname,
g.erstellt_am,
g.geaendert_am
FROM gruppen AS g
LEFT JOIN rollen_gruppen AS rg ON g.id = rg.gruppe_id
WHERE rg.rolle_id = $1;
"#,
&self.id
)
.fetch_all(pool)
.await?;
Ok(rows)
}
}

View File

@ -2,29 +2,32 @@ use anyhow::Result;
use async_graphql::{InputObject, SimpleObject};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, PgPool, Type};
use ulid::Ulid;
use crate::scalar::Id;
#[derive(SimpleObject, Debug, FromRow, Deserialize, Serialize, Type)]
pub struct Typ {
/// Die ID eines Geräte-Typs
pub id: i32,
pub id: Id,
/// Der Name eines Geräte-Typs
pub name: String,
pub typname: String,
}
#[derive(InputObject, Debug)]
pub struct TypCreateInput {
pub name: String,
pub typname: String,
}
#[derive(InputObject, Debug)]
pub struct TypUpdateInput {
pub id: i32,
pub name: Option<String>,
pub id: Id,
pub typname: Option<String>,
}
impl Typ {
pub async fn read_one(pool: &PgPool, id: &i32) -> Result<Typ> {
pub async fn read_one(pool: &PgPool, id: &Id) -> Result<Typ> {
const QUERY: &str = "SELECT * FROM typen WHERE id = $1";
let row: Typ = sqlx::query_as(QUERY).bind(id).fetch_one(pool).await?;
@ -32,7 +35,7 @@ impl Typ {
}
pub async fn read_all(pool: &PgPool) -> Result<Vec<Typ>> {
let rows = sqlx::query_as!(Typ, "SELECT id, name FROM typen")
let rows = sqlx::query_as!(Typ, "SELECT id, typname FROM typen")
.fetch_all(pool)
.await?;
@ -40,10 +43,11 @@ impl Typ {
}
pub async fn create(pool: &PgPool, input: &TypCreateInput) -> Result<Typ> {
const QUERY: &str = "INSERT INTO typen (name) VALUES ($1) RETURNING id, name";
const QUERY: &str = "INSERT INTO typen (id, typname) VALUES ($1, $2) RETURNING id, typname";
let result: Typ = sqlx::query_as(QUERY)
.bind(&input.name)
let result: Typ = sqlx::query_as::<_, Typ>(QUERY)
.bind::<Id>(Ulid::new().into())
.bind(&input.typname)
.fetch_one(pool)
.await?;
@ -52,14 +56,14 @@ impl Typ {
pub async fn create_many(pool: &PgPool, input: &[TypCreateInput]) -> Result<Vec<Typ>> {
let mut v1: Vec<&str> = Vec::new();
input.iter().for_each(|typ| v1.push(&typ.name));
input.iter().for_each(|typ| v1.push(&typ.typname));
let row = sqlx::query_as!(
Typ,
r#"
INSERT INTO typen(name)
INSERT INTO typen(typname)
SELECT * FROM UNNEST($1::text[])
RETURNING id, name"#,
RETURNING id, typname"#,
&v1 as _
)
.fetch_all(pool)
@ -70,8 +74,8 @@ impl Typ {
pub async fn update(pool: &PgPool, input: &TypUpdateInput) -> Result<Typ> {
sqlx::query!(
"UPDATE typen SET name=$1 WHERE id = $2",
input.name,
"UPDATE typen SET typname=$1 WHERE id = $2",
input.typname,
input.id
)
.execute(pool)
@ -81,7 +85,7 @@ impl Typ {
Ok(t)
}
pub async fn delete(pool: &PgPool, id: &i32) -> Result<bool> {
pub async fn delete(pool: &PgPool, id: &Id) -> Result<bool> {
let result = sqlx::query!("DELETE FROM typen WHERE id = $1", id)
.execute(pool)
.await?;

View File

@ -1,4 +1,7 @@
use crate::models::hersteller::{Hersteller, HerstellerCreateInput, HerstellerUpdateInput};
use crate::{
models::hersteller::{Hersteller, HerstellerCreateInput, HerstellerUpdateInput},
scalar::Id,
};
use async_graphql::{Context, FieldResult};
use sqlx::postgres::PgPool;
@ -27,7 +30,7 @@ impl HerstellerMutation {
Ok(row)
}
async fn delete_hersteller(&self, ctx: &Context<'_>, id: i32) -> FieldResult<bool> {
async fn delete_hersteller(&self, ctx: &Context<'_>, id: Id) -> FieldResult<bool> {
let pool = ctx.data::<PgPool>()?;
Ok(Hersteller::delete(pool, &id).await?)
}

View File

@ -1,4 +1,4 @@
use crate::models::modell::*;
use crate::{models::modell::*, scalar::Id};
use async_graphql::{Context, FieldResult};
use sqlx::postgres::PgPool;
@ -26,7 +26,7 @@ impl ModellMutation {
let row = Modell::update(pool, &input).await?;
Ok(row)
}
async fn delete_modell(&self, ctx: &Context<'_>, id: i32) -> FieldResult<bool> {
async fn delete_modell(&self, ctx: &Context<'_>, id: Id) -> FieldResult<bool> {
let pool = ctx.data::<PgPool>()?;
Ok(Modell::delete(pool, &id).await?)
}

View File

@ -1,4 +1,7 @@
use crate::models::typ::{Typ, TypCreateInput, TypUpdateInput};
use crate::{
models::typ::{Typ, TypCreateInput, TypUpdateInput},
scalar::Id,
};
use async_graphql::{Context, FieldResult};
use sqlx::postgres::PgPool;
@ -9,6 +12,7 @@ pub struct TypMutation;
impl TypMutation {
async fn create_typ(&self, ctx: &Context<'_>, input: TypCreateInput) -> FieldResult<Typ> {
let pool = ctx.data::<PgPool>()?;
let row = Typ::create(pool, &input).await?;
Ok(row)
}
@ -29,7 +33,7 @@ impl TypMutation {
Ok(row)
}
async fn delete_typ(&self, ctx: &Context<'_>, id: i32) -> FieldResult<bool> {
async fn delete_typ(&self, ctx: &Context<'_>, id: Id) -> FieldResult<bool> {
let pool = ctx.data::<PgPool>()?;
Ok(Typ::delete(pool, &id).await?)
}

26
src/queries/benutzer.rs Normal file
View File

@ -0,0 +1,26 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::postgres::PgPool;
use crate::models::benutzer::Benutzer;
#[derive(Default)]
pub struct BenutzerQuery {}
#[Object(extends)]
impl BenutzerQuery {
// async fn rolle<'a>(&self, ctx: &'a Context<'_>, id: Id) -> FieldResult<Modell> {
// let pool = ctx.data::<PgPool>()?;
// let row = Modell::read_one(pool, &id).await?;
// Ok(row)
// }
async fn benutzer_alle<'a>(&self, ctx: &'a Context<'_>) -> FieldResult<Vec<Benutzer>> {
let pool = ctx.data::<PgPool>()?;
let benutzer = sqlx::query_as!(Benutzer, "SELECT * FROM benutzer")
.fetch_all(pool)
.await?;
Ok(benutzer)
}
}

View File

@ -8,7 +8,11 @@ pub struct HerstellerQuery {}
#[Object(extends)]
impl HerstellerQuery {
async fn hersteller<'a>(&self, ctx: &'a Context<'_>, id: i32) -> FieldResult<Hersteller> {
async fn hersteller<'a>(
&self,
ctx: &'a Context<'_>,
id: uuid::Uuid,
) -> FieldResult<Hersteller> {
let pool = ctx.data::<PgPool>()?;
let row = Hersteller::read_one(pool, &id).await?;
Ok(row)

View File

@ -1,5 +1,7 @@
pub mod benutzer;
pub mod hersteller;
pub mod modell;
pub mod rolle;
pub mod typ;
use async_graphql::MergedObject;
@ -9,4 +11,6 @@ pub struct Query(
typ::TypQuery,
modell::ModellQuery,
hersteller::HerstellerQuery,
benutzer::BenutzerQuery,
rolle::RolleQuery,
);

View File

@ -1,14 +1,14 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::postgres::PgPool;
use crate::models::modell::Modell;
use crate::{models::modell::Modell, scalar::Id};
#[derive(Default)]
pub struct ModellQuery {}
#[Object(extends)]
impl ModellQuery {
async fn modell<'a>(&self, ctx: &'a Context<'_>, id: i32) -> FieldResult<Modell> {
async fn modell<'a>(&self, ctx: &'a Context<'_>, id: Id) -> FieldResult<Modell> {
let pool = ctx.data::<PgPool>()?;
let row = Modell::read_one(pool, &id).await?;
Ok(row)

27
src/queries/rolle.rs Normal file
View File

@ -0,0 +1,27 @@
use async_graphql::{Context, FieldResult, Object};
use log::debug;
use sqlx::postgres::PgPool;
use crate::models::rolle::Rolle;
#[derive(Default)]
pub struct RolleQuery {}
#[Object(extends)]
impl RolleQuery {
// async fn rolle<'a>(&self, ctx: &'a Context<'_>, id: Id) -> FieldResult<Modell> {
// let pool = ctx.data::<PgPool>()?;
// let row = Modell::read_one(pool, &id).await?;
// Ok(row)
// }
async fn rollen<'a>(&self, ctx: &'a Context<'_>) -> FieldResult<Vec<Rolle>> {
let pool = ctx.data::<PgPool>()?;
let rollen = sqlx::query_as!(Rolle, "SELECT * FROM rollen")
.fetch_all(pool)
.await?;
Ok(rollen)
}
}

View File

@ -1,7 +1,7 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::postgres::PgPool;
use crate::models::typ::Typ;
use crate::{models::typ::Typ, scalar::Id};
#[derive(Default)]
pub struct TypQuery {}
@ -14,7 +14,7 @@ impl TypQuery {
Ok(rows)
}
async fn typ<'a>(&self, ctx: &'a Context<'_>, id: i32) -> FieldResult<Typ> {
async fn typ<'a>(&self, ctx: &'a Context<'_>, id: Id) -> FieldResult<Typ> {
let pool = ctx.data::<PgPool>()?;
let row = Typ::read_one(pool, &id).await?;
Ok(row)

11
src/tree-sitter.lua Normal file
View File

@ -0,0 +1,11 @@
(macro_invocation
(scoped_identifier
path: (identifier) @path (#eq? @path "sqlx")
name: (identifier) @name (#any-of? @name "query_as" "query"))
(token_tree [
(raw_string_literal) @sql
(string_literal) @sql
]
)
(#offset! @sql 1 0 -1 0)
)