diff --git a/Cargo.lock b/Cargo.lock index 8f9b34c..df9b6c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,26 +4,26 @@ version = 3 [[package]] name = "actix-codec" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" dependencies = [ "bitflags 1.3.2", "bytes", "futures-core", "futures-sink", - "log", "memchr", "pin-project-lite", "tokio", "tokio-util", + "tracing", ] [[package]] name = "actix-cors" -version = "0.6.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414360eed71ba2d5435b185ba43ecbe281dfab5df3898286d6b7be8074372c92" +checksum = "0346d8c1f762b41b458ed3145eea914966bb9ad20b9be0d6d463b20d45586370" dependencies = [ "actix-utils", "actix-web", @@ -36,9 +36,9 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.2.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" +checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" dependencies = [ "actix-codec", "actix-rt", @@ -47,7 +47,7 @@ dependencies = [ "actix-utils", "ahash", "base64", - "bitflags 1.3.2", + "bitflags 2.4.1", "brotli", "bytes", "bytestring", @@ -68,39 +68,40 @@ dependencies = [ "rand", "sha1", "smallvec", + "tokio", + "tokio-util", "tracing", "zstd", ] [[package]] name = "actix-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 1.0.103", + "syn 2.0.41", ] [[package]] name = "actix-router" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb60846b52c118f2f04a56cc90880a274271c489b2498623d58176f8ca21fa80" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" dependencies = [ "bytestring", - "firestorm", "http", - "log", "regex", "serde", + "tracing", ] [[package]] name = "actix-rt" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" dependencies = [ "futures-core", "tokio", @@ -108,9 +109,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" dependencies = [ "actix-rt", "actix-service", @@ -118,7 +119,6 @@ dependencies = [ "futures-core", "futures-util", "mio", - "num_cpus", "socket2", "tokio", "tracing", @@ -137,28 +137,31 @@ dependencies = [ [[package]] name = "actix-tls" -version = "3.0.3" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde0cf292f7cdc7f070803cb9a0d45c018441321a78b1042ffbbb81ec333297" +checksum = "72616e7fbec0aa99c6f3164677fa48ff5a60036d0799c98cab894a44f3e0efc3" dependencies = [ - "actix-codec", "actix-rt", "actix-service", "actix-utils", "futures-core", "http", - "log", + "impl-more", "pin-project-lite", + "rustls 0.21.10", + "rustls-webpki", + "tokio", "tokio-rustls", "tokio-util", + "tracing", "webpki-roots", ] [[package]] name = "actix-utils" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" dependencies = [ "local-waker", "pin-project-lite", @@ -166,9 +169,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.2.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" +checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" dependencies = [ "actix-codec", "actix-http", @@ -189,7 +192,6 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "http", "itoa", "language-tags", "log", @@ -202,20 +204,29 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2", - "time 0.3.9", + "time", "url", ] [[package]] name = "actix-web-codegen" -version = "4.1.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" +checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", ] [[package]] @@ -226,39 +237,47 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ + "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "alloc-no-stdlib" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -270,22 +289,33 @@ dependencies = [ [[package]] name = "argon2" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27e27b63e4a34caee411ade944981136fdfa535522dc9944d6700196cbd899f" +checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" dependencies = [ "base64ct", "blake2", "password-hash", ] +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -298,9 +328,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "awc" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c60c44fbf3c8cee365e86b97d706e513b733c4eeb16437b45b88d2fffe889a" +checksum = "7fa3c705a9c7917ac0f41c0757a0a747b43bbc29b0b364b081bd7c5fc67fb223" dependencies = [ "actix-codec", "actix-http", @@ -308,7 +338,6 @@ dependencies = [ "actix-service", "actix-tls", "actix-utils", - "ahash", "base64", "bytes", "cfg-if", @@ -324,24 +353,39 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rand", - "rustls", + "rustls 0.20.9", "serde", "serde_json", "serde_urlencoded", "tokio", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" -version = "0.13.0" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.0.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -351,33 +395,33 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "blake2" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest", ] [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "brotli" -version = "3.3.4" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -386,9 +430,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.2" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -396,38 +440,39 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "bytestring" -version = "1.0.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" dependencies = [ "bytes", ] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -438,18 +483,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", - "time 0.1.43", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -460,26 +504,26 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" -version = "0.16.0" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.9", + "time", "version_check", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -495,19 +539,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" dependencies = [ "cfg-if", - "lazy_static", ] [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -515,13 +558,43 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.2.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", "num_cpus", - "parking_lot 0.12.0", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" + +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", ] [[package]] @@ -534,35 +607,48 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 1.0.103", + "syn 1.0.109", ] [[package]] name = "diesel" -version = "2.1.0" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a532c1f99a0f596f6960a60d1e119e91582b24b39e2d83a190e61262c3ef0c" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.1", "byteorder", "chrono", "diesel_derives", "itoa", - "pq-sys", - "r2d2", "serde_json", ] +[[package]] +name = "diesel-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acada1517534c92d3f382217b485db8a8638f111b0e3f2a2a8e26165050f77be" +dependencies = [ + "async-trait", + "deadpool", + "diesel", + "futures-util", + "scoped-futures", + "tokio", + "tokio-postgres", +] + [[package]] name = "diesel_derives" -version = "2.1.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74398b79d81e52e130d991afeed9c86034bb1b7735f46d2f5bf7deb261d80303" +checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.41", ] [[package]] @@ -571,14 +657,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.22", + "syn 2.0.41", ] [[package]] name = "digest" -version = "0.10.3" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -593,24 +679,24 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "either" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -620,20 +706,30 @@ dependencies = [ ] [[package]] -name = "firestorm" -version = "0.5.0" +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "finl_unicode" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3d6188b8804df28032815ea256b6955c9625c24da7525f387a7af02fbb8f01" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -645,19 +741,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -670,9 +765,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -680,15 +775,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -697,32 +792,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", ] [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-timer" @@ -732,9 +827,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -750,9 +845,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -760,15 +855,21 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "governor" version = "0.6.0" @@ -781,7 +882,7 @@ dependencies = [ "futures-timer", "no-std-compat", "nonzero_ext", - "parking_lot 0.12.0", + "parking_lot", "quanta", "rand", "smallvec", @@ -789,9 +890,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -808,9 +909,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hermit-abi" @@ -821,11 +922,26 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -834,15 +950,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -852,77 +968,82 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.47" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", "wasm-bindgen", - "winapi", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] name = "idna" -version = "0.2.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] -name = "indexmap" -version = "1.8.1" +name = "impl-more" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" -dependencies = [ - "autocfg", - "hashbrown", -] +checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ - "cfg-if", + "equivalent", + "hashbrown", ] [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -933,41 +1054,34 @@ 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.132" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "local-channel" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" dependencies = [ "futures-core", "futures-sink", - "futures-util", "local-waker", ] [[package]] name = "local-waker" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902eb695eb0591864543cbfbf6d742510642a605a61fc5e97fe6ceb5a30ac4fb" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -975,12 +1089,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach2" @@ -992,53 +1103,46 @@ dependencies = [ ] [[package]] -name = "matches" -version = "0.1.9" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] [[package]] name = "memchr" -version = "2.4.1" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.2" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "wasi", + "windows-sys", ] [[package]] @@ -1053,112 +1157,68 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] [[package]] -name = "num_threads" -version = "0.1.5" +name = "object" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.13.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", - "parking_lot_core 0.8.5", -] - -[[package]] -name = "parking_lot" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.2", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.9.2" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] name = "password-hash" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", "rand_core", @@ -1167,41 +1227,59 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.7" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1210,25 +1288,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "ppv-lite86" -version = "0.2.16" +name = "pkg-config" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] -name = "pq-sys" -version = "0.4.6" +name = "postgres-protocol" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" +checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" dependencies = [ - "vcpkg", + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", ] +[[package]] +name = "postgres-types" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +dependencies = [ + "bytes", + "fallible-iterator", + "postgres-protocol", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1244,28 +1354,28 @@ dependencies = [ "mach2", "once_cell", "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "r2d2" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot 0.11.2", + "parking_lot", "scheduled-thread-pool", ] @@ -1292,9 +1402,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -1310,18 +1420,30 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.5.5" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -1330,9 +1452,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" [[package]] name = "ring" @@ -1343,12 +1471,32 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1360,78 +1508,110 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "scheduled-thread-pool" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.11.2", + "parking_lot", +] + +[[package]] +name = "scoped-futures" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1473e24c637950c9bd38763220bea91ec3e095a89f672bbd7a10d03e77ba467" +dependencies = [ + "cfg-if", + "pin-utils", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] name = "semver" -version = "1.0.7" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.41", ] [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1452,9 +1632,20 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.4" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1463,33 +1654,42 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" -version = "0.4.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "winapi", + "windows-sys", ] [[package]] @@ -1498,17 +1698,34 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1517,9 +1734,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.22" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -1528,9 +1745,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -1546,6 +1763,7 @@ dependencies = [ "chrono", "dashmap", "diesel", + "diesel-async", "dotenv", "env_logger", "futures", @@ -1569,51 +1787,52 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", ] [[package]] name = "time" -version = "0.1.43" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ - "libc", - "winapi", + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "time" -version = "0.3.9" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" -dependencies = [ - "itoa", - "libc", - "num_threads", - "time-macros", -] +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.4" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] [[package]] name = "tinyvec" @@ -1626,26 +1845,51 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.17.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ + "backtrace", "bytes", "libc", - "memchr", "mio", - "once_cell", - "parking_lot 0.12.0", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", - "winapi", + "windows-sys", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "rand", + "socket2", + "tokio", + "tokio-util", + "whoami", ] [[package]] @@ -1654,16 +1898,16 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls", + "rustls 0.20.9", "tokio", "webpki", ] [[package]] name = "tokio-util" -version = "0.7.1" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -1675,20 +1919,19 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -1709,47 +1952,47 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -1760,45 +2003,38 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.2.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] [[package]] name = "uuid" -version = "1.2.2" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1807,9 +2043,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1817,24 +2053,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1842,28 +2078,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -1871,23 +2107,33 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1906,9 +2152,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -1919,63 +2165,115 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" -version = "0.34.0" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ + "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", + "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" -version = "0.34.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.34.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.34.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.34.0" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.34.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "zerocopy" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] [[package]] name = "zstd" -version = "0.11.2+zstd.1.5.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "6.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" dependencies = [ "libc", "zstd-sys", @@ -1983,10 +2281,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.1+zstd.1.5.2" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", + "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index c70e751..68bb9c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ regex = "1.5" tracing = "0.1.37" tracing-actix-web = "0.6.2" -diesel = { version = "2.1.0", features = ["postgres", "chrono", "r2d2", "serde_json"] } r2d2 = "0.8" log = "0.4" @@ -45,3 +44,5 @@ url = "2.2" itertools = "0.10.3" governor = "0.6.0" +diesel = { version = "2.1.0", features = ["chrono", "serde_json"] } +diesel-async = { version = "0.4.1", features = ["postgres", "deadpool"] } diff --git a/src/database/activity.rs b/src/database/activity.rs index 48974c2..706169c 100644 --- a/src/database/activity.rs +++ b/src/database/activity.rs @@ -1,5 +1,6 @@ use chrono::{prelude::*, Duration}; use diesel::prelude::*; +use diesel_async::RunQueryDsl; use crate::{ error::TimeError, @@ -19,40 +20,32 @@ impl super::DatabaseWrapper { user_id: updated_user_id, start_time: ctx_start_time, duration: ctx_duration.num_seconds() as i32, - project_name: if heartbeat.project_name.is_some() - && heartbeat.project_name.as_ref().unwrap().starts_with("tmp.") - { - Some(String::from("tmp")) - } else { - heartbeat.project_name.map(|s| s.to_lowercase()) - }, + project_name: heartbeat.project_name, language: heartbeat.language, editor_name: heartbeat.editor_name, hostname: heartbeat.hostname, }; - self.run_async_query(move |mut conn| { - use crate::schema::coding_activities::dsl::*; + let mut conn = self.db.get().await?; - diesel::insert_into(coding_activities) - .values(activity) - .execute(&mut conn)?; + use crate::schema::coding_activities::dsl::*; - Ok(()) - }) - .await?; + diesel::insert_into(coding_activities) + .values(activity) + .execute(&mut conn) + .await?; Ok(()) } pub async fn get_all_activity(&self, user: i32) -> Result, TimeError> { - self.run_async_query(move |mut conn| { - use crate::schema::coding_activities::dsl::*; - Ok(coding_activities - .filter(user_id.eq(user)) - .load::(&mut conn)?) - }) - .await + let mut conn = self.db.get().await?; + + use crate::schema::coding_activities::dsl::*; + Ok(coding_activities + .filter(user_id.eq(user)) + .load::(&mut conn) + .await?) } pub async fn get_activity( @@ -84,8 +77,8 @@ impl super::DatabaseWrapper { query = query.filter(duration.ge(min_duration)); }; - self.run_async_query(move |mut conn| Ok(query.load::(&mut conn)?)) - .await + let mut conn = self.db.get().await?; + Ok(query.load::(&mut conn).await?) } pub async fn get_user_coding_time_since( @@ -93,22 +86,25 @@ impl super::DatabaseWrapper { uid: i32, since: chrono::NaiveDateTime, ) -> Result { - self.run_async_query(move |mut conn| { - use crate::schema::coding_activities::dsl::*; - - Ok(coding_activities - .filter(user_id.eq(uid).and(start_time.ge(since))) - .select(diesel::dsl::sum(duration)) - .first::>(&mut conn)? - .unwrap_or(0) as i32) - }) - .await + let mut conn = self.db.get().await?; + + use crate::schema::coding_activities::dsl::*; + + Ok(coding_activities + .filter(user_id.eq(uid).and(start_time.ge(since))) + .select(diesel::dsl::sum(duration)) + .first::>(&mut conn) + .await? + .unwrap_or(0) as i32) } pub async fn get_coding_time_steps(&self, uid: i32) -> CodingTimeSteps { CodingTimeSteps { all_time: self - .get_user_coding_time_since(uid, chrono::NaiveDateTime::from_timestamp(0, 0)) + .get_user_coding_time_since( + uid, + chrono::NaiveDateTime::from_timestamp_opt(0, 0).unwrap(), + ) .await .unwrap_or(0), past_month: self @@ -134,14 +130,27 @@ impl super::DatabaseWrapper { from: String, to: String, ) -> Result { - self.run_async_query(move |mut conn| { - use crate::schema::coding_activities::dsl::*; - Ok(diesel::update(coding_activities) - .filter(user_id.eq(target_user_id)) - .filter(project_name.eq(from)) - .set(project_name.eq(to)) - .execute(&mut conn)?) - }) - .await + let mut conn = self.db.get().await?; + + use crate::schema::coding_activities::dsl::*; + Ok(diesel::update(coding_activities) + .filter(user_id.eq(target_user_id)) + .filter(project_name.eq(from)) + .set(project_name.eq(to)) + .execute(&mut conn) + .await?) + } + + pub async fn delete_activity(&self, userid: i32, activity: i32) -> Result { + let mut conn = self.db.get().await?; + + use crate::schema::coding_activities::dsl::*; + + Ok(diesel::delete(coding_activities.find(activity)) + // FIXME: This filter is useless? + .filter(user_id.eq(userid)) + .execute(&mut conn) + .await? + != 0) } } diff --git a/src/database/auth.rs b/src/database/auth.rs index 848ad7a..3049d7f 100644 --- a/src/database/auth.rs +++ b/src/database/auth.rs @@ -3,72 +3,85 @@ use argon2::{ Argon2, }; use diesel::prelude::*; +use diesel_async::RunQueryDsl; -use crate::{error::TimeError, models::*, utils::*}; +use crate::{ + error::TimeError, + models::*, + schema::{testaustime_users, user_identities}, + utils::*, +}; impl super::DatabaseWrapper { pub async fn user_exists(&self, target_username: String) -> Result { + let mut conn = self.db.get().await?; use crate::schema::user_identities::dsl::*; - self.run_async_query(move |mut conn| { - Ok(user_identities - .filter(username.eq(target_username)) - .first::(&mut conn) - .optional()? - .is_some()) - }) - .await + Ok(user_identities + .filter(username.eq(target_username)) + .first::(&mut conn) + .await + .optional()? + .is_some()) } pub async fn get_user_by_name( &self, target_username: String, ) -> Result { + let mut conn = self.db.get().await?; use crate::schema::user_identities::dsl::*; sql_function!(fn lower(x: diesel::sql_types::Text) -> Text); - self.run_async_query(move |mut conn| { - Ok(user_identities - .filter(lower(username).eq(target_username.to_lowercase())) - .first::(&mut conn)?) - }) - .await + Ok(user_identities + .filter(lower(username).eq(target_username.to_lowercase())) + .first::(&mut conn) + .await?) } pub async fn delete_user(&self, userid: i32) -> Result { + let mut conn = self.db.get().await?; use crate::schema::user_identities::dsl::*; - self.run_async_query(move |mut conn| { - Ok(diesel::delete(user_identities.filter(id.eq(userid))).execute(&mut conn)? > 0) - }) - .await + Ok(diesel::delete(user_identities.find(userid)) + .execute(&mut conn) + .await? + > 0) } pub async fn get_user_by_id(&self, userid: i32) -> Result { + let mut conn = self.db.get().await?; use crate::schema::user_identities::dsl::*; - self.run_async_query(move |mut conn| { - Ok(user_identities - .filter(id.eq(userid)) - .first::(&mut conn)?) - }) - .await + Ok(user_identities + .find(userid) + .first::(&mut conn) + .await?) } + // TODO: get rid of unwraps pub async fn verify_user_password( &self, - username: &str, + arg_username: &str, password: &str, ) -> Result, TimeError> { - let user = self.get_user_by_name(username.to_string()).await?; - let tuser = self.get_testaustime_user_by_id(user.id).await?; + let mut conn = self.db.get().await?; + + use user_identities::dsl::username; + + let (user, tuser) = user_identities::table + .filter(username.eq(arg_username)) + .inner_join(testaustime_users::table) + .first::<(UserIdentity, TestaustimeUser)>(&mut conn) + .await?; let argon2 = Argon2::default(); - let Ok(salt) = SaltString::new(std::str::from_utf8(&tuser.salt).unwrap()) else { + let Ok(salt) = SaltString::new(std::str::from_utf8(&tuser.salt).expect("bug: impossible")) + else { return Ok(None); // The user has no password }; let password_hash = argon2.hash_password(password.as_bytes(), &salt).unwrap(); - if password_hash.hash.unwrap().as_bytes() == tuser.password { + if password_hash.hash.expect("bug: impossible").as_bytes() == tuser.password { Ok(Some(user)) } else { Ok(None) @@ -76,21 +89,16 @@ impl super::DatabaseWrapper { } pub async fn regenerate_token(&self, userid: i32) -> Result { - let token = crate::utils::generate_token(); - - let token_clone = token.clone(); + let mut conn = self.db.get().await?; - self.run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; + let token = crate::utils::generate_token(); - diesel::update(crate::schema::user_identities::table) - .filter(id.eq(userid)) - .set(auth_token.eq(token_clone)) - .execute(&mut conn)?; + use crate::schema::user_identities::dsl::*; - Ok(()) - }) - .await?; + diesel::update(user_identities.find(userid)) + .set(auth_token.eq(&token)) + .execute(&mut conn) + .await?; Ok(token) } @@ -100,7 +108,6 @@ impl super::DatabaseWrapper { username: &str, password: &str, ) -> Result { - use crate::schema::{testaustime_users, user_identities}; if self.user_exists(username.to_string()).await? { return Err(TimeError::UserExists); } @@ -118,47 +125,68 @@ impl super::DatabaseWrapper { let new_user_clone = new_user.clone(); - self.run_async_query(move |mut conn| { - let id = diesel::insert_into(crate::schema::user_identities::table) - .values(new_user_clone) - .returning(user_identities::id) - .get_results::(&mut conn) - .map_err(|_| TimeError::UserExists)?; + let mut conn = self.db.get().await?; - let testaustime_user = NewTestaustimeUser { - password: hash.as_bytes().to_vec(), - salt: salt.as_bytes().to_vec(), - identity: id[0], - }; - - diesel::insert_into(testaustime_users::table) - .values(&testaustime_user) - .execute(&mut conn)?; - - Ok(()) - }) - .await?; + conn.build_transaction() + .read_write() + .deferrable() + .run(|mut conn| { + Box::pin(async move { + let id = diesel::insert_into(crate::schema::user_identities::table) + .values(new_user_clone) + .returning(user_identities::id) + .get_results::(&mut conn) + .await + .map_err(|_| TimeError::UserExists)?; + + let testaustime_user = NewTestaustimeUser { + password: hash.as_bytes().to_vec(), + salt: salt.as_bytes().to_vec(), + identity: id[0], + }; + + diesel::insert_into(testaustime_users::table) + .values(&testaustime_user) + .execute(&mut conn) + .await?; + + Ok::<(), TimeError>(()) + }) as _ + }) + .await?; Ok(new_user) } pub async fn change_username(&self, user: i32, new_username: String) -> Result<(), TimeError> { - if self.user_exists(new_username.to_string()).await? { - return Err(TimeError::UserExists); - } - - self.run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; - diesel::update(crate::schema::user_identities::table) - .filter(id.eq(user)) - .set(username.eq(new_username)) - .execute(&mut conn) - .map_err(|_| TimeError::UserExists)?; - Ok(()) - }) - .await?; - - Ok(()) + let mut conn = self.db.get().await?; + + conn.build_transaction() + .read_write() + .run(|mut conn| { + Box::pin(async move { + use crate::schema::user_identities::dsl::*; + + if (user_identities + .filter(username.eq(new_username.clone())) + .first::(&mut conn) + .await) + .is_ok() + { + return Err(TimeError::UserExists); + }; + + diesel::update(crate::schema::user_identities::table) + .filter(id.eq(user)) + .set(username.eq(new_username)) + .execute(&mut conn) + .await + .map_err(|_| TimeError::UserExists)?; + + Ok::<(), TimeError>(()) + }) + }) + .await } pub async fn change_password(&self, user: i32, new_password: &str) -> Result<(), TimeError> { @@ -169,47 +197,46 @@ impl super::DatabaseWrapper { .unwrap(); let new_hash = password_hash.hash.unwrap(); - self.run_async_query(move |mut conn| { - use crate::schema::testaustime_users::dsl::*; - diesel::update(crate::schema::testaustime_users::table) - .filter(identity.eq(user)) - .set(( - password.eq(&new_hash.as_bytes()), - salt.eq(new_salt.as_bytes()), - )) - .execute(&mut conn)?; - Ok(()) - }) - .await?; + let mut conn = self.db.get().await?; + + use crate::schema::testaustime_users::dsl::*; + diesel::update(crate::schema::testaustime_users::table) + .filter(identity.eq(user)) + .set(( + password.eq(&new_hash.as_bytes()), + salt.eq(new_salt.as_bytes()), + )) + .execute(&mut conn) + .await?; Ok(()) } pub async fn get_user_by_token(&self, token: String) -> Result { - let user = self - .run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; + let mut conn = self.db.get().await?; + let user = { + use crate::schema::user_identities::dsl::*; - Ok(user_identities - .filter(auth_token.eq(token)) - .first::(&mut conn)?) - }) - .await?; + user_identities + .filter(auth_token.eq(token)) + .first::(&mut conn) + .await? + }; Ok(user) } pub async fn get_testaustime_user_by_id(&self, uid: i32) -> Result { - self.run_async_query(move |mut conn| { - use crate::schema::testaustime_users::dsl::*; - - Ok(testaustime_users - .filter(identity.eq(uid)) - .first::(&mut conn)?) - }) - .await + use crate::schema::testaustime_users::dsl::*; + let mut conn = self.db.get().await?; + + Ok(testaustime_users + .filter(identity.eq(uid)) + .first::(&mut conn) + .await?) } + // FIXME: Use transactions #[cfg(feature = "testausid")] pub async fn testausid_login( &self, @@ -222,47 +249,36 @@ impl super::DatabaseWrapper { user_identities::dsl::{auth_token, id, user_identities}, }; - let user_id_arg_clone = user_id_arg.clone(); + let mut conn = self.db.get().await?; - let user_identity_opt = self - .run_async_query(move |mut conn| { - Ok(testausid_users - .filter(user_id.eq(user_id_arg_clone)) - .select(identity) - .first::(&mut conn) - .optional()?) - }) - .await?; + let user_identity_opt = testausid_users + .filter(user_id.eq(&user_id_arg)) + .select(identity) + .first::(&mut conn) + .await + .optional()?; if let Some(user_identity) = user_identity_opt { - let token = self - .run_async_query(move |mut conn| { - Ok(user_identities - .filter(id.eq(user_identity)) - .select(auth_token) - .first::(&mut conn)?) - }) + let token = user_identities + .find(user_identity) + .select(auth_token) + .first::(&mut conn) .await?; Ok(token) } else { - let token = generate_token(); let new_user = NewUserIdentity { - //FIXME: You can get around using a clone here - auth_token: token.clone(), + auth_token: generate_token(), registration_time: chrono::Local::now().naive_local(), username, friend_code: generate_friend_code(), }; - let new_user_id = self - .run_async_query(move |mut conn| { - diesel::insert_into(crate::schema::user_identities::table) - .values(&new_user) - .returning(id) - .get_results::(&mut conn) - .map_err(|_| TimeError::UserExists) - }) - .await?; + let new_user_id = diesel::insert_into(crate::schema::user_identities::table) + .values(&new_user) + .returning(id) + .get_results::(&mut conn) + .await + .map_err(|_| TimeError::UserExists)?; let testausid_user = NewTestausIdUser { user_id: user_id_arg, @@ -270,27 +286,23 @@ impl super::DatabaseWrapper { service_id: platform_id, }; - self.run_async_query(move |mut conn| { - diesel::insert_into(testausid_users) - .values(&testausid_user) - .execute(&mut conn)?; - - Ok(()) - }) - .await?; + diesel::insert_into(testausid_users) + .values(&testausid_user) + .execute(&mut conn) + .await?; - Ok(token) + Ok(new_user.auth_token) } } pub async fn change_visibility(&self, userid: i32, visibility: bool) -> Result<(), TimeError> { - self.run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; - diesel::update(user_identities.filter(id.eq(userid))) - .set(is_public.eq(visibility)) - .execute(&mut conn)?; - Ok(()) - }) - .await + let mut conn = self.db.get().await?; + + use crate::schema::user_identities::dsl::*; + diesel::update(user_identities.find(userid)) + .set(is_public.eq(visibility)) + .execute(&mut conn) + .await?; + Ok(()) } } diff --git a/src/database/friends.rs b/src/database/friends.rs index e9fbb85..119f460 100644 --- a/src/database/friends.rs +++ b/src/database/friends.rs @@ -1,23 +1,18 @@ use diesel::{insert_into, prelude::*}; -use futures_util::{ - future::OptionFuture, - stream::{self, StreamExt}, -}; +use diesel_async::RunQueryDsl; use crate::{error::TimeError, models::*}; impl super::DatabaseWrapper { pub async fn add_friend(&self, user: i32, friend: String) -> Result { - let Some(friend) = self - .run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; - - Ok(user_identities - .filter(friend_code.eq(friend)) - .first::(&mut conn) - .optional()?) - }) - .await? + let mut conn = self.db.get().await?; + use crate::schema::user_identities::dsl::*; + + let Some(friend) = user_identities + .filter(friend_code.eq(friend)) + .first::(&mut conn) + .await + .optional()? else { return Err(TimeError::UserNotFound); }; @@ -32,16 +27,13 @@ impl super::DatabaseWrapper { (friend.id, user) }; - self.run_async_query(move |mut conn| { - insert_into(crate::schema::friend_relations::table) - .values(crate::models::NewFriendRelation { - lesser_id: lesser, - greater_id: greater, - }) - .execute(&mut conn)?; - Ok(()) - }) - .await?; + insert_into(crate::schema::friend_relations::table) + .values(crate::models::NewFriendRelation { + lesser_id: lesser, + greater_id: greater, + }) + .execute(&mut conn) + .await?; Ok(friend) } @@ -53,33 +45,14 @@ impl super::DatabaseWrapper { user_identities::dsl::*, }; - let friends = self - .run_async_query(move |mut conn| { - Ok(friend_relations - .filter(greater_id.eq(user).or(lesser_id.eq(user))) - .load::(&mut conn)? - .iter() - .map( - |&FriendRelation { - lesser_id: other_lesser_id, - greater_id: other_greater_id, - .. - }| { - if other_lesser_id == user { - other_greater_id - } else { - other_lesser_id - } - }, - ) - .filter_map(|cur_friend| { - user_identities - .filter(id.eq(cur_friend)) - .first::(&mut conn) - .ok() - }) - .collect()) - }) + let mut conn = self.db.get().await?; + + let friends = friend_relations + .inner_join(user_identities.on(id.eq(lesser_id).or(id.eq(greater_id)))) + .select(user_identities::all_columns()) + .distinct() + .filter(id.ne(user)) + .load::(&mut conn) .await?; Ok(friends) @@ -91,49 +64,61 @@ impl super::DatabaseWrapper { user_identities::dsl::*, }; - let friends = stream::iter( - self.run_async_query(move |mut conn| { - Ok(friend_relations - .filter(greater_id.eq(user).or(lesser_id.eq(user))) - .load::(&mut conn)? - .iter() - .map(|fr| { - if fr.lesser_id == user { - fr.greater_id - } else { - fr.lesser_id - } - }) - .collect::>()) + let mut conn = self.db.get().await?; + + let friends = friend_relations + .filter(lesser_id.eq(user).or(greater_id.eq(user))) + .inner_join(user_identities.on(id.eq(lesser_id).or(id.eq(greater_id)))) + .distinct() + .filter(id.ne(user)) + .select(user_identities::all_columns()) + .load::(&mut conn) + .await?; + + // FIXME: A further optimization could be applied + // by calculating the aggrigates (CodingTimeSteps) + // in the database. This can be done in a single SQL-query + // but due to limitations with diesel we would have to do it + // in a separate function called for example: coding_time_steps_for_users(ids: Vec) + let friends_with_time = CodingActivity::belonging_to(&friends) + .load::(&mut conn) + .await? + .grouped_by(&friends) + .iter() + .zip(friends) + .map(|(d, u)| FriendWithTime { + user: u, + coding_time: CodingTimeSteps { + all_time: d.iter().map(|a| a.duration).sum(), + past_month: d + .iter() + .map(|a| { + if a.start_time + >= chrono::Local::now().naive_local() - chrono::Duration::days(30) + { + a.duration + } else { + 0 + } + }) + .sum(), + past_week: d + .iter() + .map(|a| { + if a.start_time + >= chrono::Local::now().naive_local() - chrono::Duration::days(7) + { + a.duration + } else { + 0 + } + }) + .sum(), + }, }) - .await?, - ) - .then(|cur_friend| async move { - let opt_friends = self - .run_async_query(move |mut conn| { - Ok(user_identities - .filter(id.eq(cur_friend)) - .first::(&mut conn) - .ok()) - }) - .await - .unwrap(); - - let future: OptionFuture<_> = opt_friends - .map(|friend| async { - FriendWithTime { - coding_time: self.get_coding_time_steps(friend.id).await, - user: friend, - } - }) - .into(); - - future.await.unwrap() - }) - .collect::>() - .await; + .collect::>(); - Ok(friends) + Ok(friends_with_time) } pub async fn are_friends(&self, user: i32, friend_id: i32) -> Result { @@ -144,14 +129,14 @@ impl super::DatabaseWrapper { (friend_id, user) }; - self.run_async_query(move |mut conn| { - Ok(friend_relations - .filter(lesser_id.eq(lesser).and(greater_id.eq(greater))) - .first::(&mut conn) - .optional()? - .is_some()) - }) - .await + let mut conn = self.db.get().await?; + + Ok(friend_relations + .filter(lesser_id.eq(lesser).and(greater_id.eq(greater))) + .first::(&mut conn) + .await + .optional()? + .is_some()) } pub async fn remove_friend(&self, user: i32, friend_id: i32) -> Result { @@ -162,13 +147,13 @@ impl super::DatabaseWrapper { (friend_id, user) }; - self.run_async_query(move |mut conn| { - Ok(diesel::delete(friend_relations) - .filter(lesser_id.eq(lesser).and(greater_id.eq(greater))) - .execute(&mut conn)? - != 0) - }) - .await + let mut conn = self.db.get().await?; + + Ok(diesel::delete(friend_relations) + .filter(lesser_id.eq(lesser).and(greater_id.eq(greater))) + .execute(&mut conn) + .await? + != 0) } pub async fn regenerate_friend_code(&self, userid: i32) -> Result { @@ -176,15 +161,12 @@ impl super::DatabaseWrapper { let code = crate::utils::generate_friend_code(); let code_clone = code.clone(); - self.run_async_query(move |mut conn| { - diesel::update(crate::schema::user_identities::table) - .filter(id.eq(userid)) - .set(friend_code.eq(code_clone)) - .execute(&mut conn)?; + let mut conn = self.db.get().await?; - Ok(()) - }) - .await?; + diesel::update(user_identities.find(userid)) + .set(friend_code.eq(code_clone)) + .execute(&mut conn) + .await?; Ok(code) } diff --git a/src/database/leaderboards.rs b/src/database/leaderboards.rs index 28cc62e..6ff5151 100644 --- a/src/database/leaderboards.rs +++ b/src/database/leaderboards.rs @@ -2,25 +2,21 @@ use std::collections::HashMap; use chrono::prelude::*; use diesel::{insert_into, prelude::*}; - -use crate::{api::users::ListLeaderboard, error::TimeError, models::*}; +use diesel_async::RunQueryDsl; +use futures_util::TryStreamExt; + +use crate::{ + api::users::ListLeaderboard, + error::TimeError, + models::*, + schema::{ + coding_activities, + leaderboard_members::{self, user_id}, + user_identities, + }, +}; impl super::DatabaseWrapper { - pub async fn delete_activity(&self, userid: i32, activity: i32) -> Result { - use crate::schema::coding_activities::dsl::*; - - let res = self - .run_async_query(move |mut conn| { - Ok(diesel::delete(crate::schema::coding_activities::table) - .filter(id.eq(activity)) - .filter(user_id.eq(userid)) - .execute(&mut conn)?) - }) - .await?; - - Ok(res != 0) - } - pub async fn create_leaderboard( &self, creator_id: i32, @@ -33,32 +29,36 @@ impl super::DatabaseWrapper { invite_code: code.clone(), }; - let lid = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; - - Ok(insert_into(crate::schema::leaderboards::table) - .values(&board) - .returning(id) - .get_results(&mut conn)?[0]) + let mut conn = self.db.get().await?; + + conn.build_transaction() + .read_write() + .run(|mut conn| { + Box::pin(async move { + use crate::schema::leaderboards::dsl::*; + + let lid = insert_into(crate::schema::leaderboards::table) + .values(&board) + .returning(id) + .get_results(&mut conn) + .await?[0]; + + let admin = NewLeaderboardMember { + user_id: creator_id, + admin: true, + leaderboard_id: lid, + }; + + insert_into(crate::schema::leaderboard_members::table) + .values(admin) + .execute(&mut conn) + .await?; + + Ok::<(), TimeError>(()) + }) }) .await?; - let admin = NewLeaderboardMember { - user_id: creator_id, - admin: true, - leaderboard_id: lid, - }; - - self.run_async_query(move |mut conn| { - insert_into(crate::schema::leaderboard_members::table) - .values(admin) - .execute(&mut conn)?; - - Ok(()) - }) - .await?; - Ok(code) } @@ -67,91 +67,90 @@ impl super::DatabaseWrapper { let newinvite_clone = newinvite.clone(); - self.run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; - diesel::update(crate::schema::leaderboards::table) - .filter(id.eq(lid)) - .set(invite_code.eq(newinvite_clone)) - .execute(&mut conn)?; - Ok(()) - }) - .await?; + let mut conn = self.db.get().await?; + + use crate::schema::leaderboards::dsl::*; + diesel::update(leaderboards.find(lid)) + .set(invite_code.eq(newinvite_clone)) + .execute(&mut conn) + .await?; Ok(newinvite) } pub async fn delete_leaderboard(&self, lname: String) -> Result { - let res = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; - Ok(diesel::delete(crate::schema::leaderboards::table) - .filter(name.eq(lname)) - .execute(&mut conn)?) - }) - .await?; - - Ok(res != 0) + let mut conn = self.db.get().await?; + + use crate::schema::leaderboards::dsl::*; + Ok(diesel::delete(crate::schema::leaderboards::table) + .filter(name.eq(lname)) + .execute(&mut conn) + .await? + != 0) } pub async fn get_leaderboard_id_by_name(&self, lname: String) -> Result { - self.run_async_query(move |mut conn| { - sql_function!(fn lower(x: diesel::sql_types::Text) -> Text); - use crate::schema::leaderboards::dsl::*; + sql_function!(fn lower(x: diesel::sql_types::Text) -> Text); + use crate::schema::leaderboards::dsl::*; - Ok(leaderboards - .filter(lower(name).eq(lname.to_lowercase())) - .select(id) - .first::(&mut conn)?) - }) - .await + let mut conn = self.db.get().await?; + + Ok(leaderboards + .filter(lower(name).eq(lname.to_lowercase())) + .select(id) + .first::(&mut conn) + .await?) } pub async fn get_leaderboard(&self, lname: String) -> Result { sql_function!(fn lower(x: diesel::sql_types::Text) -> Text); - let board = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; + let mut conn = self.db.get().await?; - Ok(leaderboards - .filter(lower(name).eq(lname.to_lowercase())) - .first::(&mut conn)?) - }) - .await?; + let board = { + use crate::schema::leaderboards::dsl::*; + + leaderboards + .filter(lower(name).eq(lname.to_lowercase())) + .first::(&mut conn) + .await? + }; - let members = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboard_members::dsl::*; + use crate::schema::{ + coding_activities::dsl::start_time, + user_identities::dsl::{id, user_identities}, + }; - Ok(leaderboard_members - .filter(leaderboard_id.eq(board.id)) - .load::(&mut conn)?) - }) + let members = LeaderboardMember::belonging_to(&board) + .inner_join(user_identities.on(id.eq(user_id))) + .load::<(LeaderboardMember, UserIdentity)>(&mut conn) .await?; - let mut fullmembers = Vec::new(); let aweekago = NaiveDateTime::new( - chrono::Local::today().naive_local() - chrono::Duration::weeks(1), - chrono::NaiveTime::from_num_seconds_from_midnight(0, 0), + Local::now().date_naive() - chrono::Duration::weeks(1), + chrono::NaiveTime::from_num_seconds_from_midnight_opt(0, 0).unwrap(), ); - for m in members { - if let Ok(user) = self.get_user_by_id(m.user_id).await { - fullmembers.push(PrivateLeaderboardMember { - id: m.id, - username: user.username, + let members = + CodingActivity::belonging_to(&members.iter().map(|(_, u)| u).collect::>()) + .filter(start_time.ge(aweekago)) + .load::(&mut conn) + .await? + .grouped_by(&members.iter().map(|(_, u)| u).collect::>()) + .iter() + .zip(members.iter()) + .map(|(d, (m, u))| PrivateLeaderboardMember { + id: u.id, + username: u.username.clone(), admin: m.admin, - time_coded: self - .get_user_coding_time_since(m.user_id, aweekago) - .await - .unwrap_or(0), - }); - } - } + time_coded: d.iter().map(|a| a.duration).sum(), + }) + .collect::>(); + Ok(PrivateLeaderboard { name: board.name, invite: board.invite_code, creation_time: board.creation_time, - members: fullmembers, + members, }) } @@ -160,41 +159,47 @@ impl super::DatabaseWrapper { uid: i32, invite: String, ) -> Result { - let (lid, name) = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; - Ok(leaderboards - .filter(invite_code.eq(invite)) - .select((id, name)) - .first::<(i32, String)>(&mut conn)?) - }) + use crate::schema::leaderboards::dsl::{invite_code, leaderboards}; + + let mut conn = self.db.get().await?; + + let board = leaderboards + .filter(invite_code.eq(invite)) + .first::(&mut conn) .await?; let user = NewLeaderboardMember { user_id: uid, - leaderboard_id: lid, + leaderboard_id: board.id, admin: false, }; - self.run_async_query(move |mut conn| { - insert_into(crate::schema::leaderboard_members::table) - .values(&user) - .execute(&mut conn)?; - Ok(()) - }) - .await?; - - let member_count: i32 = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboard_members::dsl::*; - Ok(leaderboard_members - .filter(leaderboard_id.eq(lid)) - .select(diesel::dsl::count(user_id)) - .first::(&mut conn)? as i32) + let name = board.name.clone(); + + let member_count = conn + .build_transaction() + .read_write() + .run(|mut conn| { + Box::pin(async move { + diesel::insert_into(leaderboard_members::table) + .values(&user) + .execute(&mut conn) + .await?; + + Ok::( + LeaderboardMember::belonging_to(&board) + .count() + .first::(&mut conn) + .await?, + ) + }) }) .await?; - Ok(crate::api::users::MinimalLeaderboard { name, member_count }) + Ok(crate::api::users::MinimalLeaderboard { + name, + member_count: member_count as i32, + }) } pub async fn remove_user_from_leaderboard( @@ -203,15 +208,14 @@ impl super::DatabaseWrapper { uid: i32, ) -> Result { use crate::schema::leaderboard_members::dsl::*; - let res = self - .run_async_query(move |mut conn| { - Ok(diesel::delete(crate::schema::leaderboard_members::table) - .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) - .execute(&mut conn)?) - }) - .await?; - Ok(res != 0) + let mut conn = self.db.get().await?; + + Ok(diesel::delete(crate::schema::leaderboard_members::table) + .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) + .execute(&mut conn) + .await? + != 0) } pub async fn promote_user_to_leaderboard_admin( @@ -220,16 +224,14 @@ impl super::DatabaseWrapper { uid: i32, ) -> Result { use crate::schema::leaderboard_members::dsl::*; - let res = self - .run_async_query(move |mut conn| { - Ok(diesel::update(crate::schema::leaderboard_members::table) - .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) - .set(admin.eq(true)) - .execute(&mut conn)?) - }) - .await?; - Ok(res != 0) + let mut conn = self.db.get().await?; + Ok(diesel::update(crate::schema::leaderboard_members::table) + .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) + .set(admin.eq(true)) + .execute(&mut conn) + .await? + != 0) } pub async fn demote_user_to_leaderboard_member( @@ -237,136 +239,147 @@ impl super::DatabaseWrapper { lid: i32, uid: i32, ) -> Result { - let res = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboard_members::dsl::*; - - Ok(diesel::update(crate::schema::leaderboard_members::table) - .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) - .set(admin.eq(false)) - .execute(&mut conn)?) - }) - .await?; - Ok(res != 0) + use crate::schema::leaderboard_members::dsl::*; + + let mut conn = self.db.get().await?; + Ok(diesel::update(crate::schema::leaderboard_members::table) + .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) + .set(admin.eq(false)) + .execute(&mut conn) + .await? + != 0) } pub async fn is_leaderboard_member(&self, uid: i32, lid: i32) -> Result { - self.run_async_query(move |mut conn| { - use crate::schema::leaderboard_members::dsl::*; - - Ok(leaderboard_members - .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) - .select(id) - .first::(&mut conn) - .optional()? - .is_some()) - }) - .await + let mut conn = self.db.get().await?; + use crate::schema::leaderboard_members::dsl::*; + + Ok(leaderboard_members + .filter(user_id.eq(uid).and(leaderboard_id.eq(lid))) + .select(id) + .first::(&mut conn) + .await + .optional()? + .is_some()) } pub async fn is_leaderboard_admin(&self, uid: i32, lid: i32) -> Result { use crate::schema::leaderboard_members::dsl::*; - self.run_async_query(move |mut conn| { - Ok(leaderboard_members - .filter(leaderboard_id.eq(lid).and(user_id.eq(uid))) - .select(admin) - .first::(&mut conn) - .optional()? - .unwrap_or(false)) - }) - .await + let mut conn = self.db.get().await?; + + Ok(leaderboard_members + .filter(leaderboard_id.eq(lid).and(user_id.eq(uid))) + .select(admin) + .first::(&mut conn) + .await + .optional()? + .unwrap_or(false)) } pub async fn get_leaderboard_admin_count(&self, lid: i32) -> Result { use crate::schema::leaderboard_members::dsl::*; - self.run_async_query(move |mut conn| { - Ok(leaderboard_members - .filter(leaderboard_id.eq(lid).and(admin.eq(true))) - .select(diesel::dsl::count(user_id)) - .first::(&mut conn)?) - }) - .await + let mut conn = self.db.get().await?; + + Ok(leaderboard_members + .filter(leaderboard_id.eq(lid).and(admin.eq(true))) + .select(diesel::dsl::count(user_id)) + .first::(&mut conn) + .await?) } pub async fn get_user_leaderboards( &self, uid: i32, ) -> Result, TimeError> { - let ids = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboard_members::dsl::*; - - Ok(leaderboard_members - .filter(user_id.eq(uid)) - .select(leaderboard_id) - .order_by(leaderboard_id.asc()) - .load::(&mut conn)?) - }) - .await?; + let mut conn = self.db.get().await?; - let members = self - .run_async_query(move |mut conn| { - use crate::schema::leaderboards::dsl::*; - let ls = leaderboards - .filter(id.eq_any(&ids)) - .order_by(id.asc()) - .load::(&mut conn)?; - - let mut members: HashMap> = HashMap::new(); - for l in &ls { - members.insert(l.clone(), { - use crate::schema::leaderboard_members::dsl::*; - leaderboard_members - .filter(leaderboard_id.eq(l.id)) - .load::(&mut conn)? - }); - } + let user = user_identities::table + .find(uid) + .first::(&mut conn) + .await?; - Ok(members) - }) + let boards = LeaderboardMember::belonging_to(&user) + .inner_join(crate::schema::leaderboards::table) + .select(crate::schema::leaderboards::dsl::leaderboards::all_columns()) + .load::(&mut conn) .await?; let aweekago = NaiveDateTime::new( - chrono::Local::today().naive_local() - chrono::Duration::weeks(1), - chrono::NaiveTime::from_num_seconds_from_midnight(0, 0), + Local::now().date_naive() - chrono::Duration::weeks(1), + chrono::NaiveTime::from_num_seconds_from_midnight_opt(0, 0).unwrap(), ); - // FIXME: cache members - let mut fullmembers = HashMap::new(); - for (l, ms) in members { - let mut full = Vec::new(); - for m in ms { - if let Ok(user) = self.get_user_by_id(m.user_id).await { - full.push(PrivateLeaderboardMember { + // FIXME: We could maybe use limit here because we only need the + // user and the top member + let members = LeaderboardMember::belonging_to(&boards.iter().collect::>()) + //.inner_join(crate::schema::user_identities::table) + .left_join( + crate::schema::coding_activities::table.on(leaderboard_members::dsl::user_id + .eq(coding_activities::dsl::user_id) + .and(coding_activities::dsl::start_time.ge(aweekago))), + ) + .group_by(leaderboard_members::dsl::id) + .select(( + leaderboard_members::dsl::leaderboard_members::all_columns(), + // NOTE: This is a work-around (diesel has some issues with group_by) + diesel::dsl::sql::( + "COALESCE(SUM(coding_activities.duration), 0) AS coding_time", + ), + )) + .order_by(diesel::dsl::sql::("coding_time").desc()) + .load::<(LeaderboardMember, i64)>(&mut conn) + .await?; + + let usernames = LeaderboardMember::belonging_to(&boards.iter().collect::>()) + .inner_join(crate::schema::user_identities::table) + .group_by(user_identities::dsl::id) + .select((user_identities::dsl::id, user_identities::dsl::username)) + .load_stream::<(i32, String)>(&mut conn) + .await? + .try_fold(HashMap::new(), |mut acc, (id, name)| { + acc.insert(id, name); + futures_util::future::ready(Ok(acc)) + }) + .await?; + + let members_populated = members + .iter() + .map(|(m, t)| { + ( + m.leaderboard_id, + PrivateLeaderboardMember { id: m.user_id, - username: user.username, + username: usernames[&m.user_id].clone(), admin: m.admin, - time_coded: self - .get_user_coding_time_since(m.user_id, aweekago) - .await - .unwrap_or(0), - }); + time_coded: *t as i32, + }, + ) + }) + .collect::>(); + + Ok(boards + .iter() + .map(|b| { + let bms = members_populated + .iter() + .filter(|(lid, _)| *lid == b.id) + .map(|(_, m)| m) + .collect::>(); + + let (my_position, me) = bms + .iter() + .enumerate() + .find(|(_, m)| m.id == user.id) + .expect("bug: impossible"); + ListLeaderboard { + name: b.name.clone(), + member_count: bms.len() as i32, + // NOTE: Sorted in the query + top_member: bms[0].clone(), + my_position: my_position as i32 + 1, + me: (*me).clone(), } - } - fullmembers.insert(l, full); - } - - let mut ret = Vec::new(); - for (l, mut ms) in fullmembers { - ms.sort_by_key(|m| m.time_coded); - // NOTE: Leaderboards can't be empty here as they have to contain user - let mypos = ms.iter().position(|m| m.id == uid).unwrap(); - let me = ms.get(mypos).unwrap(); - let top = ms.last().unwrap(); - ret.push(ListLeaderboard { - name: l.name, - me: me.clone(), - my_position: (mypos + 1) as i32, - member_count: ms.len() as i32, - top_member: top.clone(), }) - } - - Ok(ret) + .collect::>()) } } diff --git a/src/database/misc.rs b/src/database/misc.rs index 256744b..662c4c9 100644 --- a/src/database/misc.rs +++ b/src/database/misc.rs @@ -1,42 +1,41 @@ use diesel::prelude::*; +use diesel_async::RunQueryDsl; use crate::{error::TimeError, models::*}; impl super::DatabaseWrapper { pub async fn search_public_users(&self, search: String) -> Result, TimeError> { - self.run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; - Ok(user_identities - .filter(is_public.eq(true)) - .filter(username.like(format!("%{search}%"))) - .load::(&mut conn)? - .into_iter() - .map(|u| u.into()) - .collect()) - }) - .await + let mut conn = self.db.get().await?; + + use crate::schema::user_identities::dsl::*; + Ok(user_identities + .filter(is_public.eq(true)) + .filter(username.like(format!("%{search}%"))) + .load::(&mut conn) + .await? + .into_iter() + .map(|u| u.into()) + .collect()) } pub async fn get_total_user_count(&self) -> Result { - self.run_async_query(move |mut conn| { - use crate::schema::user_identities::dsl::*; + let mut conn = self.db.get().await?; - Ok(user_identities.count().first::(&mut conn)? as u64) - }) - .await + use crate::schema::user_identities::dsl::*; + Ok(user_identities.count().first::(&mut conn).await? as u64) } pub async fn get_total_coding_time(&self) -> Result { - self.run_async_query(move |mut conn| { - use diesel::dsl::sum; + let mut conn = self.db.get().await?; + + use diesel::dsl::sum; - use crate::schema::coding_activities::dsl::*; + use crate::schema::coding_activities::dsl::*; - Ok(coding_activities - .select(sum(duration)) - .first::>(&mut conn)? - .unwrap_or_default() as u64) - }) - .await + Ok(coding_activities + .select(sum(duration)) + .first::>(&mut conn) + .await? + .unwrap_or_default() as u64) } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 1f6bfd0..3fa976b 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -1,13 +1,12 @@ use std::{future::Future, pin::Pin, sync::Arc}; -use actix_web::{ - dev::Payload, - web::{block, Data}, - FromRequest, HttpRequest, -}; -use diesel::{ - prelude::*, - r2d2::{ConnectionManager, Pool}, +use actix_web::{dev::Payload, web::Data, FromRequest, HttpRequest}; +use diesel_async::{ + pooled_connection::{ + deadpool::{Object, Pool}, + AsyncDieselConnectionManager, + }, + AsyncPgConnection, }; use crate::error::TimeError; @@ -18,10 +17,10 @@ pub mod friends; pub mod leaderboards; pub mod misc; -type DatabaseConnection = diesel::r2d2::PooledConnection>; +type DatabaseConnection = Object; pub struct Database { - backend: Pool>, + backend: Pool, } pub struct DatabaseWrapper { @@ -46,25 +45,17 @@ impl FromRequest for DatabaseWrapper { } impl Database { - fn get(&self) -> Result { - Ok(self.backend.get()?) + async fn get(&self) -> Result { + Ok(self.backend.get().await?) } - pub fn new(pool: Pool>) -> Self { - Self { backend: pool } - } -} + pub fn new(url: String) -> Self { + let manager = AsyncDieselConnectionManager::::new(url); -impl DatabaseWrapper { - async fn run_async_query< - T: Send + 'static, - F: FnOnce(DatabaseConnection) -> Result + Send + 'static, - >( - &self, - query: F, - ) -> Result { - let conn = self.db.get()?; + let pool = Pool::builder(manager) + .build() + .expect("Failed to create connection pool"); - block(move || query(conn)).await? + Self { backend: pool } } } diff --git a/src/error.rs b/src/error.rs index 0781fc5..d05e852 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,6 +9,8 @@ use thiserror::Error; pub enum TimeError { #[error("Failed to connect to database connection pool")] R2d2Error(#[from] r2d2::Error), + #[error("Failed to connect to database connection pool")] + DeadpoolError(#[from] diesel_async::pooled_connection::deadpool::PoolError), #[error("Diesel transaction failed `{0}`")] DieselError(#[from] diesel::result::Error), #[error("Internal server error")] diff --git a/src/main.rs b/src/main.rs index 8f73952..0a17dbb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,10 +26,6 @@ use awc::Client; use chrono::NaiveDateTime; use dashmap::DashMap; use database::Database; -use diesel::{ - r2d2::{ConnectionManager, Pool}, - PgConnection, -}; use governor::{Quota, RateLimiter}; use ratelimiter::TestaustimeRateLimiter; use serde_derive::Deserialize; @@ -88,13 +84,7 @@ async fn main() -> std::io::Result<()> { toml::from_str(&std::fs::read_to_string("settings.toml").expect("Missing settings.toml")) .expect("Invalid Toml in settings.toml"); - let manager = ConnectionManager::::new(config.database_url); - - let pool = Pool::builder() - .build(manager) - .expect("Failed to create connection pool"); - - let database = Data::new(Database::new(pool)); + let database = Data::new(Database::new(config.database_url)); let register_limiter = Data::new(RegisterLimiter { limit_by_peer_ip: config.ratelimit_by_peer_ip, diff --git a/src/models.rs b/src/models.rs index 5259b2f..028be3d 100644 --- a/src/models.rs +++ b/src/models.rs @@ -6,7 +6,8 @@ pub struct UserId { pub id: i32, } -#[derive(Queryable, Clone, Debug, Serialize, PartialEq, Eq)] +#[derive(Identifiable, Queryable, Clone, Debug, Serialize, PartialEq, Eq)] +#[diesel(table_name = user_identities)] pub struct UserIdentity { pub id: i32, #[serde(skip_serializing)] @@ -34,7 +35,9 @@ impl From for PublicUser { } } -#[derive(Queryable, Clone, Debug, Serialize)] +#[derive(Queryable, Clone, Debug, Serialize, Identifiable, Associations)] +#[diesel(belongs_to(UserIdentity, foreign_key=identity))] +#[diesel(table_name = testaustime_users)] pub struct TestaustimeUser { pub id: i32, #[serde(skip_serializing)] @@ -56,8 +59,6 @@ pub struct NewTestaustimeUser { pub identity: i32, } -// This is here so that vilepis doesn't actually give friends each others' auth tokens -// Fuck off #[derive(Clone, Debug, Serialize)] pub struct SelfUser { pub id: i32, @@ -94,7 +95,9 @@ pub struct NewTestausIdUser { } #[cfg(feature = "testausid")] -#[derive(Queryable, Serialize, Clone)] +#[derive(Queryable, Serialize, Clone, Associations, Identifiable)] +#[diesel(belongs_to(UserIdentity, foreign_key=identity))] +#[diesel(table_name = testausid_users)] pub struct TestausIdUser { pub id: i32, pub user_id: String, @@ -113,7 +116,9 @@ pub struct NewUserIdentity { pub registration_time: chrono::NaiveDateTime, } -#[derive(Queryable, Clone, Debug)] +// NOTE: It is impossible to use diesel::assocations here +// https://github.com/diesel-rs/diesel/issues/2142 +#[derive(Queryable, Clone, Debug, Identifiable)] pub struct FriendRelation { pub id: i32, pub lesser_id: i32, @@ -129,7 +134,9 @@ pub struct NewFriendRelation { pub greater_id: i32, } -#[derive(Queryable, Clone, Debug, Serialize)] +#[derive(Queryable, Clone, Debug, Serialize, Identifiable, Associations)] +#[diesel(belongs_to(UserIdentity, foreign_key=user_id))] +#[diesel(table_name = coding_activities)] pub struct CodingActivity { pub id: i32, #[serde(skip_serializing)] @@ -156,7 +163,7 @@ pub struct NewCodingActivity { pub hostname: Option, } -#[derive(Queryable, Clone, Debug, Serialize, Hash, Eq, PartialEq)] +#[derive(Queryable, Clone, Debug, Serialize, Hash, Eq, PartialEq, Identifiable)] pub struct Leaderboard { pub id: i32, pub name: String, @@ -174,7 +181,10 @@ pub struct NewLeaderboard { pub creation_time: chrono::NaiveDateTime, } -#[derive(Queryable, Clone, Debug)] +#[derive(Queryable, Clone, Debug, Identifiable, Associations)] +#[diesel(belongs_to(Leaderboard))] +#[diesel(belongs_to(UserIdentity, foreign_key=user_id))] +#[diesel(table_name = leaderboard_members)] pub struct LeaderboardMember { pub id: i32, pub leaderboard_id: i32, diff --git a/src/requests.rs b/src/requests.rs index 235b3b9..dabe4b1 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -1,14 +1,29 @@ use chrono::{serde::ts_seconds_option, DateTime, Utc}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; #[derive(Deserialize, Serialize, Debug, Hash, Eq, PartialEq, Clone)] pub struct HeartBeat { + #[serde(deserialize_with = "project_deserialize")] pub project_name: Option, pub language: Option, pub editor_name: Option, pub hostname: Option, } +fn project_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let project = Option::::deserialize(deserializer)?; + Ok(project.map(|p| { + if p.starts_with("tmp.") { + String::from("tmp") + } else { + p + } + })) +} + #[derive(Deserialize, Debug)] pub struct DataRequest { #[serde(default)]