Бэкенд: по сути монго готово, пусть и белиберда
This commit is contained in:
parent
6abd323314
commit
8184781b2d
587
backend/Cargo.lock
generated
587
backend/Cargo.lock
generated
@ -30,7 +30,7 @@ dependencies = [
|
||||
"actix-service",
|
||||
"actix-utils",
|
||||
"ahash 0.8.3",
|
||||
"base64",
|
||||
"base64 0.21.0",
|
||||
"bitflags",
|
||||
"brotli",
|
||||
"bytes",
|
||||
@ -277,8 +277,10 @@ dependencies = [
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"dotenv_codegen",
|
||||
"futures",
|
||||
"mongodb",
|
||||
"nanoid",
|
||||
"pbkdf2",
|
||||
"pbkdf2 0.12.1",
|
||||
"rust_decimal",
|
||||
"rust_decimal_macros",
|
||||
"serde",
|
||||
@ -288,6 +290,12 @@ dependencies = [
|
||||
"tokio-postgres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
@ -387,6 +395,28 @@ dependencies = [
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bson"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aeb8bae494e49dbc330dd23cf78f6f7accee22f640ce3ab17841badaa4ce232"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
"base64 0.13.1",
|
||||
"bitvec",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
"time 0.3.20",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
@ -572,6 +602,58 @@ dependencies = [
|
||||
"syn 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
@ -581,7 +663,7 @@ dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"rustc_version 0.4.0",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
@ -634,6 +716,18 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-as-inner"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
@ -671,6 +765,21 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.28"
|
||||
@ -687,6 +796,23 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
@ -716,10 +842,13 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
@ -774,6 +903,12 @@ dependencies = [
|
||||
"ahash 0.7.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
@ -783,6 +918,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
@ -792,6 +933,17 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"match_cfg",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
@ -839,6 +991,23 @@ dependencies = [
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
@ -859,6 +1028,24 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipconfig"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be"
|
||||
dependencies = [
|
||||
"socket2 0.4.9",
|
||||
"widestring",
|
||||
"winapi",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
@ -889,6 +1076,12 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
@ -904,6 +1097,12 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "local-channel"
|
||||
version = "0.1.3"
|
||||
@ -941,6 +1140,27 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-cache"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "match_cfg"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.5"
|
||||
@ -983,6 +1203,53 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mongodb"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebe15399de63ad4294c80069967736cbb87ebe467a8cd0629df9cab88a6fbde6"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.1",
|
||||
"bitflags",
|
||||
"bson",
|
||||
"chrono",
|
||||
"derivative",
|
||||
"derive_more",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"hmac",
|
||||
"lazy_static",
|
||||
"md-5",
|
||||
"pbkdf2 0.11.0",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"rustc_version_runtime",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_with",
|
||||
"sha-1",
|
||||
"sha2",
|
||||
"socket2 0.4.9",
|
||||
"stringprep",
|
||||
"strsim",
|
||||
"take_mut",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"trust-dns-proto",
|
||||
"trust-dns-resolver",
|
||||
"typed-builder",
|
||||
"uuid",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanoid"
|
||||
version = "0.4.0"
|
||||
@ -1056,6 +1323,15 @@ version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.12.1"
|
||||
@ -1128,7 +1404,7 @@ version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.21.0",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"fallible-iterator",
|
||||
@ -1202,6 +1478,12 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
@ -1282,6 +1564,31 @@ dependencies = [
|
||||
"bytecheck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resolv-conf"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||
dependencies = [
|
||||
"hostname",
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkyv"
|
||||
version = "0.7.42"
|
||||
@ -1340,13 +1647,53 @@ dependencies = [
|
||||
"rust_decimal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"semver 1.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version_runtime"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d31b7153270ebf48bf91c65ae5b0c00e749c4cfad505f66530ac74950249582f"
|
||||
dependencies = [
|
||||
"rustc_version 0.2.3",
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.20.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1367,18 +1714,43 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "seahash"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.159"
|
||||
@ -1388,6 +1760,15 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_bytes"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.159"
|
||||
@ -1405,6 +1786,7 @@ version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
@ -1422,6 +1804,39 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_with_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
@ -1500,6 +1915,12 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.2"
|
||||
@ -1510,6 +1931,12 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
@ -1538,6 +1965,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take_mut"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
@ -1553,6 +1986,26 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
@ -1660,6 +2113,17 @@ dependencies = [
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
@ -1668,6 +2132,7 @@ checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
@ -1704,6 +2169,62 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-proto"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if",
|
||||
"data-encoding",
|
||||
"enum-as-inner",
|
||||
"futures-channel",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"idna 0.2.3",
|
||||
"ipnet",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rand",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-resolver"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
"ipconfig",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lru-cache",
|
||||
"parking_lot",
|
||||
"resolv-conf",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"trust-dns-proto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-builder"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
@ -1737,6 +2258,12 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
@ -1744,7 +2271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"idna 0.3.0",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
@ -1753,6 +2280,10 @@ name = "uuid"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
@ -1826,6 +2357,41 @@ version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -1932,6 +2498,15 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
|
@ -19,4 +19,6 @@ pbkdf2 = "0.12.1"
|
||||
nanoid = "0.4.0"
|
||||
sha2 = "0.10.6"
|
||||
rust_decimal = { version = "1.29", features = ["db-tokio-postgres"] }
|
||||
rust_decimal_macros = "1.29"
|
||||
rust_decimal_macros = "1.29"
|
||||
mongodb = { version = "2.5.0", features = ["bson-chrono-0_4"] }
|
||||
futures = "0.3"
|
@ -6,6 +6,8 @@ use backend::endpoints::{auth::*};
|
||||
use backend::storages::postgres::administrator::PostgresAdministratorRepository;
|
||||
use dotenv_codegen::dotenv;
|
||||
use backend::{State, services};
|
||||
use mongodb::Client;
|
||||
use mongodb::options::ClientOptions;
|
||||
use tokio_postgres::NoTls;
|
||||
use backend::storages::postgres::car::PostgresCarRepository;
|
||||
use backend::storages::postgres::car_station::PostgresCarStationRepository;
|
||||
@ -13,6 +15,14 @@ use backend::storages::postgres::client::PostgresClientRepository;
|
||||
use backend::storages::postgres::rent::PostgresRentRepository;
|
||||
use backend::storages::postgres::owner::PostgresOwnerRepository;
|
||||
use backend::storages::postgres::benchmark::PostgresBenchmarkRepository;
|
||||
use backend::storages::mongo::car::MongoCarRepository;
|
||||
use backend::storages::mongo::car_station::MongoCarStationRepository;
|
||||
use backend::storages::mongo::administrator::MongoAdministratorRepository;
|
||||
use backend::storages::mongo::client::MongoClientRepository;
|
||||
use backend::storages::mongo::rent::MongoRentRepository;
|
||||
use backend::storages::mongo::owner::MongoOwnerRepository;
|
||||
use backend::storages::mongo::benchmark::MongoBenchmarkRepository;
|
||||
use backend::storages::*;
|
||||
use backend::endpoints::car_station::*;
|
||||
use backend::endpoints::car::*;
|
||||
use backend::endpoints::client::*;
|
||||
@ -21,32 +31,52 @@ use backend::endpoints::owner::*;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let (client, connection) = tokio_postgres::connect(
|
||||
&format!("host={} user={} password={} dbname={}", dotenv!("HOST"), dotenv!("USERR"), dotenv!("PASSWORD"), dotenv!("DBNAMEE")),
|
||||
NoTls
|
||||
).await.unwrap();
|
||||
// let (client, connection) = tokio_postgres::connect(
|
||||
// &format!("host={} user={} password={} dbname={}", dotenv!("HOST"), dotenv!("USERR"), dotenv!("PASSWORD"), dotenv!("DBNAMEE")),
|
||||
// NoTls
|
||||
// ).await.unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = connection.await {
|
||||
eprintln!("connection error: {}", e);
|
||||
}
|
||||
});
|
||||
// tokio::spawn(async move {
|
||||
// if let Err(e) = connection.await {
|
||||
// eprintln!("connection error: {}", e);
|
||||
// }
|
||||
// });
|
||||
|
||||
let client = Arc::new(client);
|
||||
// let client = Arc::new(client);
|
||||
|
||||
let car_repository = PostgresCarRepository { connection: Arc::clone(&client) };
|
||||
// let car_repository = PostgresCarRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let car_station_repository = PostgresCarStationRepository { connection: Arc::clone(&client) };
|
||||
// let car_station_repository = PostgresCarStationRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let client_repository = PostgresClientRepository { connection: Arc::clone(&client) };
|
||||
// let client_repository = PostgresClientRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let owner_repository = PostgresOwnerRepository { connection: Arc::clone(&client) };
|
||||
// let owner_repository = PostgresOwnerRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let rent_repository = PostgresRentRepository { connection: Arc::clone(&client) };
|
||||
// let rent_repository = PostgresRentRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let administrator_repository = PostgresAdministratorRepository { connection: Arc::clone(&client) };
|
||||
// let administrator_repository = PostgresAdministratorRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let benchmark_repository = PostgresBenchmarkRepository { connection: Arc::clone(&client) };
|
||||
// let benchmark_repository = PostgresBenchmarkRepository { connection: Arc::clone(&client) };
|
||||
|
||||
let client_options = ClientOptions::parse(dotenv!("MONGO")).await.unwrap();
|
||||
|
||||
let client = Client::with_options(client_options).unwrap();
|
||||
|
||||
let db = Arc::new(client.database("default_db"));
|
||||
|
||||
let car_repository = MongoCarRepository { database: Arc::clone(&db) };
|
||||
|
||||
let car_station_repository = MongoCarStationRepository { database: Arc::clone(&db) };
|
||||
|
||||
let client_repository = MongoClientRepository { database: Arc::clone(&db) };
|
||||
|
||||
let owner_repository = MongoOwnerRepository { database: Arc::clone(&db) };
|
||||
|
||||
let rent_repository = MongoRentRepository { database: Arc::clone(&db) };
|
||||
|
||||
let administrator_repository = MongoAdministratorRepository { database: Arc::clone(&db) };
|
||||
|
||||
let benchmark_repository = MongoBenchmarkRepository { database: Arc::clone(&db) };
|
||||
|
||||
let auth_service = services::auth::AuthService::new();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rust_decimal::Decimal;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Car {
|
||||
pub id: String,
|
||||
pub brand: String,
|
||||
|
63
backend/src/storages/mongo/administrator.rs
Normal file
63
backend/src/storages/mongo/administrator.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::FindOptions;
|
||||
use std::sync::Arc;
|
||||
use crate::models::administrator::*;
|
||||
use crate::storages::traits::AdministratorRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
||||
pub struct MongoAdministratorRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AdministratorRepository for MongoAdministratorRepository {
|
||||
async fn read(&self, id: String) -> Result<Administrator, String> {
|
||||
let collection = self.database.collection::<Document>("administrators");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.find_one(filter, None).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let username = document.get_str("username").unwrap().to_string();
|
||||
let password = document.get_str("password").unwrap().to_string();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let car_station_id = document.get_object_id("car_station_id").unwrap().to_hex();
|
||||
let administrator = Administrator {id, username, password, name, surname, middlename, car_station_id};
|
||||
Ok(administrator)
|
||||
},
|
||||
Ok(None) => Err("Administrator not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_by_username(&self, username: &str) -> Result<Administrator, String> {
|
||||
let collection = self.database.collection::<Document>("administrators");
|
||||
let filter = doc! {
|
||||
"username": username.to_string()
|
||||
};
|
||||
let result = collection.find_one(filter, None).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let username = document.get_str("username").unwrap().to_string();
|
||||
let password = document.get_str("password").unwrap().to_string();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let car_station_id = document.get_object_id("car_station_id").unwrap().to_hex();
|
||||
let administrator = Administrator {id, username, password, name, surname, middlename, car_station_id};
|
||||
Ok(administrator)
|
||||
},
|
||||
Ok(None) => Err("Administrator not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
68
backend/src/storages/mongo/benchmark.rs
Normal file
68
backend/src/storages/mongo/benchmark.rs
Normal file
@ -0,0 +1,68 @@
|
||||
use chrono::Utc;
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::{FindOptions, AggregateOptions};
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::prelude::{ToPrimitive, FromPrimitive};
|
||||
use std::default;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::storages::traits::BenchmarkRepository;
|
||||
|
||||
|
||||
pub struct MongoBenchmarkRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl BenchmarkRepository for MongoBenchmarkRepository {
|
||||
async fn benchmark(&self) -> Result<i64, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
|
||||
collection.delete_many(doc! {}, None).await.unwrap();
|
||||
|
||||
let start_time = Utc::now().naive_local();
|
||||
|
||||
for i in 1..2001 {
|
||||
let car_id = ObjectId::new();
|
||||
let client_id = ObjectId::new();
|
||||
let owner_id = ObjectId::new();
|
||||
let rent_id = ObjectId::new();
|
||||
|
||||
collection.insert_one(doc! {
|
||||
"_id": client_id,
|
||||
"name": format!("Иван{}", i),
|
||||
"surname": format!("Иванов{}", i),
|
||||
"middlename": format!("Иванович{}", i),
|
||||
"phone": i.to_string(),
|
||||
"rents": [{
|
||||
"_id": rent_id,
|
||||
"start_time": chrono::Utc::now(),
|
||||
"time_amount": i,
|
||||
"car_id": car_id.clone()
|
||||
}]
|
||||
}, None).await.unwrap();
|
||||
|
||||
collection.insert_one(doc! {
|
||||
"_id": owner_id,
|
||||
"name": format!("Петр{}", i),
|
||||
"surname": format!("Петров{}", i),
|
||||
"middlename": format!("Петрович{}", i),
|
||||
"phone": i.to_string(),
|
||||
"rents": [],
|
||||
"cars": [{
|
||||
"_id": car_id,
|
||||
"brand": format!("Лада{}", i),
|
||||
"model": format!("Гранта{}", i),
|
||||
"price": i as f64,
|
||||
"car_station_id": ObjectId::parse_str("6466ca4c26b3b0b31d9a45bc").unwrap()
|
||||
}]
|
||||
}, None).await.unwrap();
|
||||
}
|
||||
|
||||
return Ok((Utc::now().naive_local() - start_time).num_microseconds().unwrap())
|
||||
}
|
||||
}
|
221
backend/src/storages/mongo/car.rs
Normal file
221
backend/src/storages/mongo/car.rs
Normal file
@ -0,0 +1,221 @@
|
||||
use chrono::{Utc, Months};
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::{FindOptions, AggregateOptions};
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::prelude::{ToPrimitive, FromPrimitive};
|
||||
use std::default;
|
||||
use std::sync::Arc;
|
||||
use crate::models::car::*;
|
||||
use crate::storages::traits::*;
|
||||
use async_trait::async_trait;
|
||||
|
||||
use super::rent::MongoRentRepository;
|
||||
|
||||
|
||||
pub struct MongoCarRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CarRepository for MongoCarRepository {
|
||||
async fn create(&self, car: BindingCar) -> Result<Car, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let document = doc! {
|
||||
"_id": ObjectId::parse_str(car.owner_id.clone()).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$push": {
|
||||
"cars": doc! {
|
||||
"_id": ObjectId::new(),
|
||||
"brand": car.brand.clone(),
|
||||
"model": car.model.clone(),
|
||||
"price": car.price.to_f64().unwrap(),
|
||||
"car_station_id": ObjectId::parse_str(car.car_station_id.to_string()).unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(document, update, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
let brand = car.brand.clone();
|
||||
let model = car.model.clone();
|
||||
let price = car.price;
|
||||
let car_station_id = car.car_station_id.clone();
|
||||
let owner_id = car.owner_id.clone();
|
||||
let car = Car { id: "".to_string(), brand, model, car_station_id, price, owner_id};
|
||||
Ok(car)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(&self, id: String) -> Result<Car, String> {
|
||||
match self.read_all().await.unwrap().into_iter().filter(|c| c.id.starts_with(&id)).next() {
|
||||
Some(car) => Ok(car),
|
||||
None => Err("Car not found".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all(&self) -> Result<Vec<Car>, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let mut cursor = collection.find(doc! {"cars": { "$exists": true }}, None).await.map_err(|e| e.to_string())?;
|
||||
let mut cars = Vec::new();
|
||||
while let Some(result) = cursor.next().await {
|
||||
match result {
|
||||
Ok(document) => {
|
||||
for car_document in document.get_array("cars").unwrap() {
|
||||
let car = car_document.as_document().unwrap();
|
||||
let id = car.get("_id").unwrap().as_object_id().unwrap().to_hex();
|
||||
let brand = car.get_str("brand").unwrap().to_string();
|
||||
let model = car.get_str("model").unwrap().to_string();
|
||||
let price = Decimal::from_f64(car.get_f64("price").unwrap()).unwrap();
|
||||
let car_station_id = car.get_object_id("car_station_id").unwrap().to_hex();
|
||||
let owner_id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let car = Car { id, brand, model, car_station_id, price, owner_id};
|
||||
cars.push(car);
|
||||
}
|
||||
},
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
}
|
||||
Ok(cars)
|
||||
}
|
||||
|
||||
async fn update(&self, id: String, car: BindingCar) -> Result<Car, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let mut cursor = collection.find(None, None).await.map_err(|e| e.to_string())?;
|
||||
while let Some(result) = cursor.next().await {
|
||||
match result {
|
||||
Ok(document) => {
|
||||
for (i, car_document) in document.get_array("cars").unwrap().into_iter().enumerate() {
|
||||
if car_document.as_document().unwrap().get_object_id("_id").unwrap().to_hex().starts_with(&id) {
|
||||
collection.update_one(doc! {
|
||||
"_id": ObjectId::parse_str(document.get_str("_id").unwrap()).unwrap()
|
||||
}, doc! {
|
||||
"$set": doc! {
|
||||
format!("cars.${}.brand", i): car.brand.clone(),
|
||||
format!("cars.${}.model", i): car.model.clone(),
|
||||
format!("cars.${}.price", i): car.price.to_f64().unwrap(),
|
||||
format!("cars.${}.car_station_id", i): ObjectId::parse_str(car.car_station_id.clone()).unwrap(),
|
||||
}
|
||||
}, None).await.unwrap();
|
||||
|
||||
return Ok(Car {..Default::default()})
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Err("Car not found".to_string())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: String) -> Result<(), String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let document = doc! {
|
||||
"cars._id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$pull": {
|
||||
"cars": {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(document, update, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
if result.modified_count == 0 {
|
||||
Err("Car not found".to_string())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_report(&self) -> Result<Vec<Report>, String> {
|
||||
let mut reports = Vec::new();
|
||||
|
||||
let rents = (MongoRentRepository {database: Arc::clone(&self.database)}).read_all().await.unwrap();
|
||||
let cars = self.read_all().await.unwrap();
|
||||
|
||||
for car in cars {
|
||||
let mut times = 0;
|
||||
let mut sum = Decimal::from_f64(0.0).unwrap();
|
||||
|
||||
for rent in rents.iter() {
|
||||
if rent.car_id.starts_with(&car.id) && rent.time_amount.is_some() {
|
||||
times += 1;
|
||||
sum += car.price * Decimal::from(rent.time_amount.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
reports.push(Report {car_id: car.id.clone(), brand: car.brand.clone(), model: car.model.clone(), times, income: sum})
|
||||
}
|
||||
// let pipeline = vec![
|
||||
// doc! {
|
||||
// "$match": {
|
||||
// "rents.start_time": {
|
||||
// "$gte": Utc::now().checked_sub_months(Months::new(1)).unwrap(),
|
||||
// "$lt": Utc::now().checked_add_months(Months::new(1)).unwrap()
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// doc! {
|
||||
// "$lookup": {
|
||||
// "from": "cars",
|
||||
// "localField": "rents.car_id",
|
||||
// "foreignField": "_id",
|
||||
// "as": "car"
|
||||
// }
|
||||
// },
|
||||
// doc! {
|
||||
// "$unwind": "$car"
|
||||
// },
|
||||
// doc! {
|
||||
// "$group": {
|
||||
// "_id": "$rents.car_id",
|
||||
// "brand": { "$first": "$car.brand" },
|
||||
// "model": { "$first": "$car.model" },
|
||||
// "times": { "$sum": 1 },
|
||||
// "income": { "$sum": { "$multiply": [ "$car.price", "$rents.time_amount" ] } }
|
||||
// }
|
||||
// },
|
||||
// doc! {
|
||||
// "$project": {
|
||||
// "_id": 0,
|
||||
// "car_id": { "$toString": "$_id" },
|
||||
// "brand": 1,
|
||||
// "model": 1,
|
||||
// "times": 1,
|
||||
// "income": { "$round": [ "$income", 2 ] }
|
||||
// }
|
||||
// }
|
||||
// ];
|
||||
// let collection = self.database.collection::<Document>("clients");
|
||||
// let options = AggregateOptions::builder().build();
|
||||
// let cursor = collection.aggregate(pipeline, options).await.unwrap();
|
||||
|
||||
// let reports = cursor
|
||||
// .map(|doc| {
|
||||
// let doc = doc.unwrap();
|
||||
// let car_id = doc.get_str("car_id").unwrap().to_owned();
|
||||
// let brand = doc.get_str("brand").unwrap().to_owned();
|
||||
// let model = doc.get_str("model").unwrap().to_owned();
|
||||
// let times = doc.get_i64("times").unwrap();
|
||||
// let income = Decimal::from_f64(doc.get_f64("income").unwrap()).unwrap();
|
||||
|
||||
// Report { car_id, brand, model, times, income }
|
||||
// })
|
||||
// .collect::<Vec<_>>()
|
||||
// .await;
|
||||
|
||||
Ok(reports)
|
||||
}
|
||||
}
|
101
backend/src/storages/mongo/car_station.rs
Normal file
101
backend/src/storages/mongo/car_station.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::FindOptions;
|
||||
use std::sync::Arc;
|
||||
use crate::models::car_station::*;
|
||||
use crate::storages::traits::CarStationRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
||||
pub struct MongoCarStationRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CarStationRepository for MongoCarStationRepository {
|
||||
async fn create(&self, car_station: BindingCarStation) -> Result<CarStation, String> {
|
||||
let collection = self.database.collection::<Document>("car_stations");
|
||||
let document = doc! {
|
||||
"address": car_station.address.clone()
|
||||
};
|
||||
let result = collection.insert_one(document, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
let id = result.inserted_id.as_object_id().unwrap().to_hex();
|
||||
let car_station = CarStation { id, address: car_station.address };
|
||||
Ok(car_station)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(&self, id: String) -> Result<CarStation, String> {
|
||||
let collection = self.database.collection::<Document>("car_stations");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.find_one(filter, None).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let address = document.get_str("address").unwrap().to_string();
|
||||
let car_station = CarStation { id, address };
|
||||
Ok(car_station)
|
||||
},
|
||||
Ok(None) => Err("Car station not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all(&self) -> Result<Vec<CarStation>, String> {
|
||||
let collection = self.database.collection::<Document>("car_stations");
|
||||
let mut cursor = collection.find(None, None).await.map_err(|e| e.to_string())?;
|
||||
let mut car_stations = Vec::new();
|
||||
while let Some(result) = cursor.next().await {
|
||||
match result {
|
||||
Ok(document) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let address = document.get_str("address").unwrap().to_string();
|
||||
let car_station = CarStation { id, address };
|
||||
car_stations.push(car_station);
|
||||
},
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
}
|
||||
Ok(car_stations)
|
||||
}
|
||||
|
||||
async fn update(&self, id: String, car_station: BindingCarStation) -> Result<CarStation, String> {
|
||||
let collection = self.database.collection::<Document>("car_stations");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$set": {
|
||||
"address": car_station.address.clone()
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let car_station = CarStation { id, address: car_station.address };
|
||||
Ok(car_station)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(&self, id: String) -> Result<(), String> {
|
||||
let collection = self.database.collection::<Document>("car_stations");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.delete_one(filter, None).await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
117
backend/src/storages/mongo/client.rs
Normal file
117
backend/src/storages/mongo/client.rs
Normal file
@ -0,0 +1,117 @@
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::{FindOptions, AggregateOptions};
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::prelude::{ToPrimitive, FromPrimitive};
|
||||
use std::default;
|
||||
use std::sync::Arc;
|
||||
use crate::models::client::*;
|
||||
use crate::storages::traits::ClientRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
||||
pub struct MongoClientRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ClientRepository for MongoClientRepository {
|
||||
async fn create(&self, client: BindingClient) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let document = doc! {
|
||||
"name": client.name.clone(),
|
||||
"surname": client.surname.clone(),
|
||||
"middlename": client.middlename.clone(),
|
||||
"phone": client.phone.clone(),
|
||||
"rents": Bson::Array(Vec::<Bson>::new())
|
||||
};
|
||||
let result = collection.insert_one(document, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
let id = result.inserted_id.as_object_id().unwrap().to_hex();
|
||||
let client = Client { id, name: client.name, surname: client.surname, middlename: client.middlename, phone: client.phone };
|
||||
Ok(client)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(&self, id: String) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.find_one(filter, None).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").map(|s| s.to_string());
|
||||
let phone = document.get_str("phone").unwrap().to_string();
|
||||
let client = Client { id, name, surname, middlename: Some(middlename.unwrap()), phone };
|
||||
Ok(client)
|
||||
},
|
||||
Ok(None) => Err("Client not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all(&self) -> Result<Vec<Client>, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let mut cursor = collection.find(None, None).await.map_err(|e| e.to_string())?;
|
||||
let mut clients = Vec::new();
|
||||
while let Some(result) = cursor.next().await {
|
||||
match result {
|
||||
Ok(document) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").map(|s| s.to_string());
|
||||
let phone = document.get_str("phone").unwrap().to_string();
|
||||
let client = Client { id, name, surname, middlename: Some(middlename.unwrap()), phone };
|
||||
clients.push(client);
|
||||
},
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
}
|
||||
Ok(clients)
|
||||
}
|
||||
|
||||
async fn update(&self, id: String, client: BindingClient) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$set": {
|
||||
"name": client.name.clone(),
|
||||
"surname": client.surname.clone(),
|
||||
"middlename": client.middlename.clone(),
|
||||
"phone": client.phone.clone()
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let client = Client { id, name: client.name, surname: client.surname, middlename: client.middlename, phone: client.phone };
|
||||
Ok(client)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(&self, id: String) -> Result<(), String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.delete_one(filter, None).await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
pub mod car_station;
|
||||
pub mod administrator;
|
||||
pub mod car;
|
||||
pub mod client;
|
||||
pub mod owner;
|
||||
pub mod rent;
|
||||
pub mod benchmark;
|
129
backend/src/storages/mongo/owner.rs
Normal file
129
backend/src/storages/mongo/owner.rs
Normal file
@ -0,0 +1,129 @@
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::{FindOptions, AggregateOptions};
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::prelude::{ToPrimitive, FromPrimitive};
|
||||
use std::default;
|
||||
use std::sync::Arc;
|
||||
use crate::models::client::*;
|
||||
use crate::storages::traits::OwnerRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
||||
|
||||
pub struct MongoOwnerRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl OwnerRepository for MongoOwnerRepository {
|
||||
async fn create(&self, owner: BindingClient) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let document = doc! {
|
||||
"name": owner.name.clone(),
|
||||
"surname": owner.surname.clone(),
|
||||
"middlename": owner.middlename.clone(),
|
||||
"phone": owner.phone.clone(),
|
||||
"cars": Bson::Array(Vec::<Bson>::new()),
|
||||
"rents": Bson::Array(Vec::<Bson>::new())
|
||||
};
|
||||
let result = collection.insert_one(document, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
let id = result.inserted_id.as_object_id().unwrap().to_hex();
|
||||
let owner = Client { id, name: owner.name, surname: owner.surname, middlename: owner.middlename, phone: owner.phone };
|
||||
Ok(owner)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(&self, id: String) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.find_one(filter, None).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").map(|s| s.to_string());
|
||||
let phone = document.get_str("phone").unwrap().to_string();
|
||||
let owner = Client { id, name, surname, middlename: Some(middlename.unwrap()), phone };
|
||||
Ok(owner)
|
||||
},
|
||||
Ok(None) => Err("Owner not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all(&self) -> Result<Vec<Client>, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let mut cursor = collection.find(doc! {"cars": { "$exists": true }}, None).await.map_err(|e| e.to_string())?;
|
||||
let mut owners = Vec::new();
|
||||
while let Some(result) = cursor.next().await {
|
||||
match result {
|
||||
Ok(document) => {
|
||||
let id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let name = document.get_str("name").unwrap().to_string();
|
||||
let surname = document.get_str("surname").unwrap().to_string();
|
||||
let middlename = document.get_str("middlename").map(|s| s.to_string());
|
||||
let phone = document.get_str("phone").unwrap().to_string();
|
||||
let owner = Client { id, name, surname, middlename: Some(middlename.unwrap()), phone };
|
||||
owners.push(owner);
|
||||
},
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
}
|
||||
Ok(owners)
|
||||
}
|
||||
|
||||
async fn update(&self, id: String, owner: BindingClient) -> Result<Client, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$set": {
|
||||
"name": owner.name.clone(),
|
||||
"surname": owner.surname.clone(),
|
||||
"middlename": owner.middlename.clone(),
|
||||
"phone": owner.phone.clone()
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
if result.modified_count == 1 {
|
||||
let owner = self.read(id).await?;
|
||||
Ok(owner)
|
||||
} else {
|
||||
Err("Owner not found".to_string())
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(&self, id: String) -> Result<(), String> {
|
||||
let collection = self.database.collection::<Document>("owners");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let result = collection.delete_one(filter, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
if result.deleted_count == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Owner not found".to_string())
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
153
backend/src/storages/mongo/rent.rs
Normal file
153
backend/src/storages/mongo/rent.rs
Normal file
@ -0,0 +1,153 @@
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use mongodb::Database;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::bson::{doc, Document, Bson};
|
||||
use futures::stream::{TryStreamExt, StreamExt};
|
||||
use mongodb::options::{FindOptions, AggregateOptions, FindOneOptions};
|
||||
use rust_decimal::Decimal;
|
||||
use rust_decimal::prelude::{ToPrimitive, FromPrimitive};
|
||||
use std::default;
|
||||
use std::sync::Arc;
|
||||
use crate::models::rent::*;
|
||||
use crate::storages::traits::RentRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
||||
pub struct MongoRentRepository {
|
||||
pub database: Arc<Database>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl RentRepository for MongoRentRepository {
|
||||
async fn create(&self, rent: BindingRent) -> Result<Rent, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let start_time = chrono::Utc::now();
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&rent.client_id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$push": {
|
||||
"rents": {
|
||||
"_id": ObjectId::new(),
|
||||
"start_time": start_time,
|
||||
"time_amount": Bson::Null,
|
||||
"car_id": ObjectId::parse_str(&rent.car_id).unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
match result {
|
||||
Ok(result) => {
|
||||
if result.modified_count == 1 {
|
||||
Ok(Rent {id: "".to_string(), start_time: Default::default(), time_amount: None, car_id: "".to_string(), client_id: "".to_string()})
|
||||
} else {
|
||||
Err("Rent not found".to_string())
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(&self, id: String) -> Result<Rent, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"rents._id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let projection = doc! {
|
||||
"rents.$": 1
|
||||
};
|
||||
let options = FindOneOptions::builder().projection(projection).build();
|
||||
let result = collection.find_one(filter, options).await;
|
||||
match result {
|
||||
Ok(Some(document)) => {
|
||||
let rent_document = document.get_array("rents").unwrap().get(0).unwrap().as_document().unwrap();
|
||||
let client_id = document.get_object_id("_id").unwrap().to_hex();
|
||||
let id = rent_document.get_object_id("_id").unwrap().to_hex();
|
||||
let start_time = rent_document.get_datetime("start_time").unwrap();
|
||||
let time_amount = rent_document.get_i32("time_amount").ok();
|
||||
let car_id = rent_document.get_object_id("car_id").unwrap().to_hex();
|
||||
let rent = Rent { id, start_time: NaiveDateTime::from_timestamp_millis(start_time.timestamp_millis()).unwrap(), time_amount, client_id, car_id };
|
||||
Ok(rent)
|
||||
},
|
||||
Ok(None) => Err("Rent not found".to_string()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all(&self) -> Result<Vec<Rent>, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let result = collection.find(None, None).await;
|
||||
match result {
|
||||
Ok(mut cursor) => {
|
||||
let mut rents = Vec::new();
|
||||
while let Some(document) = cursor.next().await {
|
||||
let another = document.clone().unwrap();
|
||||
let rents_array = another.get_array("rents").unwrap();
|
||||
let client_id = document.unwrap().get_object_id("_id").unwrap().to_hex();
|
||||
for rent_document in rents_array.iter().map(|x| x.as_document().unwrap()) {
|
||||
let id = rent_document.get_object_id("_id").unwrap().to_hex();
|
||||
let start_time = rent_document.get_datetime("start_time").unwrap();
|
||||
let time_amount = rent_document.get_i32("time_amount").ok();
|
||||
let car_id = rent_document.get_object_id("car_id").unwrap().to_hex();
|
||||
let rent = Rent { id, start_time: NaiveDateTime::from_timestamp_millis(start_time.timestamp_millis()).unwrap(), time_amount, client_id: client_id.clone(), car_id };
|
||||
rents.push(rent);
|
||||
}
|
||||
}
|
||||
Ok(rents)
|
||||
},
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(&self, id: String, rent: BindingRent) -> Result<Rent, String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(&rent.client_id).unwrap(),
|
||||
"rents._id": ObjectId::parse_str(&id).unwrap()
|
||||
};
|
||||
let update = doc! {
|
||||
"$set": {
|
||||
"rents.$.time_amount": rent.time_amount
|
||||
}
|
||||
};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
match result {
|
||||
Ok(success) => self.read(success.upserted_id.unwrap().as_object_id().unwrap().to_hex()).await,
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete(&self, id: String) -> Result<(), String> {
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let rent = self.read(id.clone()).await.unwrap();
|
||||
let filter = doc! {
|
||||
"_id": ObjectId::parse_str(rent.client_id.clone()).unwrap(),
|
||||
"rents._id": ObjectId::parse_str(id.clone()).unwrap()
|
||||
};
|
||||
let result = collection.update_one(filter, doc! {"$pull": {"rents": {"_id": ObjectId::parse_str(id.clone()).unwrap()}}}, None).await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
async fn end_rent(&self, id: String) -> Result<(), String> {
|
||||
let rent = self.read(id.clone()).await?;
|
||||
|
||||
if rent.time_amount.is_some() {
|
||||
return Err("Rent is already ended".to_owned());
|
||||
}
|
||||
|
||||
let time_amount = (Utc::now().naive_local() - rent.start_time).num_minutes() as i32;
|
||||
|
||||
let collection = self.database.collection::<Document>("clients");
|
||||
let filter = doc! {"_id": ObjectId::parse_str(&rent.client_id).unwrap(), "rents._id": ObjectId::parse_str(&rent.id).unwrap()};
|
||||
let update = doc! {"$set": {"rents.$.time_amount": time_amount}};
|
||||
let result = collection.update_one(filter, update, None).await;
|
||||
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user