commit ce45ef847e9ef87b5b555680b5fe91598101185a Author: Tait Hoyem Date: Mon Mar 27 18:43:36 2023 -0600 Initial commit; this should have been done way earlier diff --git a/.env b/.env new file mode 100644 index 0000000..e147f8d --- /dev/null +++ b/.env @@ -0,0 +1 @@ +export DATABASE_URL="postgresql://ibihf2:ibihf@localhost/ibihf" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..05389c8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1782 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "async-stream" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.9", +] + +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f8ccfd9221ee7d1f3d4b33e1f8319b3a81ed8f61f2ea40b37b859794b4491" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-macros" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb524613be645939e280b7279f7b017f98cf7f5ef084ec374df373530e73277" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.9", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cxx" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 1.0.109", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-sink" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" + +[[package]] +name = "futures-task" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" + +[[package]] +name = "futures-util" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ibihf" +version = "0.1.0" +dependencies = [ + "axum", + "axum-macros", + "chrono", + "serde", + "serde_plain", + "serde_tuple", + "sql-builder", + "sqlx", + "static_assertions", + "tokio", + "tokio-test", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[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.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.9", +] + +[[package]] +name = "serde_json" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_plain" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_tuple" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f025b91216f15a2a32aa39669329a475733590a015835d1783549a56d09427" +dependencies = [ + "serde", + "serde_tuple_macros", +] + +[[package]] +name = "serde_tuple_macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4076151d1a2b688e25aaf236997933c66e18b870d0369f8b248b8ab2be630d7e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "sql-builder" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" +dependencies = [ + "anyhow", + "thiserror", +] + +[[package]] +name = "sqlformat" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +dependencies = [ + "ahash", + "atoi", + "base64 0.13.1", + "bitflags", + "byteorder", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "dirs", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "hkdf", + "hmac", + "indexmap", + "itoa", + "libc", + "log", + "md-5", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rand", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "time 0.3.20", + "tokio-stream", + "url", + "webpki-roots", + "whoami", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da4a3c17e109f700685ec577c0f85efd9b19bcf15c913985f14dc1ac01775aa" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.9", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-test" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3" +dependencies = [ + "async-stream", + "bytes", + "futures-core", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "whoami" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9051b0e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ibihf" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum = { version = "0.6.12" } +axum-macros = "0.3.7" +chrono = { version = "0.4.24", features = ["serde"] } +serde = "1.0.158" +serde_plain = "1.0.1" +serde_tuple = "0.5.0" +sql-builder = "3.1.1" +sqlx = { version = "0.6.3", features = ["postgres", "runtime-tokio-rustls", "time", "chrono"] } +static_assertions = "1.1.0" +tokio = { version = "1.26.0", features = ["rt-multi-thread", "macros" ] } + +[dev-dependencies] +tokio-test = "0.4.2" diff --git a/migrations/20230324221302_add_leagues.down.sql b/migrations/20230324221302_add_leagues.down.sql new file mode 100644 index 0000000..f0162e6 --- /dev/null +++ b/migrations/20230324221302_add_leagues.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE leagues; diff --git a/migrations/20230324221302_add_leagues.up.sql b/migrations/20230324221302_add_leagues.up.sql new file mode 100644 index 0000000..7b98765 --- /dev/null +++ b/migrations/20230324221302_add_leagues.up.sql @@ -0,0 +1,7 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS leagues ( + id SERIAL PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + start_date TIMESTAMPTZ NOT NULL, + end_date TIMESTAMPTZ +); diff --git a/migrations/20230324221305_create_division.down.sql b/migrations/20230324221305_create_division.down.sql new file mode 100644 index 0000000..04b4fde --- /dev/null +++ b/migrations/20230324221305_create_division.down.sql @@ -0,0 +1 @@ +DROP TABLE divisions; diff --git a/migrations/20230324221305_create_division.up.sql b/migrations/20230324221305_create_division.up.sql new file mode 100644 index 0000000..061e1b6 --- /dev/null +++ b/migrations/20230324221305_create_division.up.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS divisions ( + id SERIAL PRIMARY KEY NOT NULL, + league INTEGER NOT NULL, + name VARCHAR(255) NOT NULL, + CONSTRAINT league_fk + FOREIGN KEY(league) + REFERENCES leagues(id) + ON DELETE RESTRICT +); diff --git a/migrations/20230324224957_create_teams.down.sql b/migrations/20230324224957_create_teams.down.sql new file mode 100644 index 0000000..e60bc62 --- /dev/null +++ b/migrations/20230324224957_create_teams.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS teams; diff --git a/migrations/20230324224957_create_teams.up.sql b/migrations/20230324224957_create_teams.up.sql new file mode 100644 index 0000000..781c494 --- /dev/null +++ b/migrations/20230324224957_create_teams.up.sql @@ -0,0 +1,10 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS teams ( + id SERIAL PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + division INTEGER NOT NULL, + CONSTRAINT division_fk + FOREIGN KEY(division) + REFERENCES divisions(id) + ON DELETE RESTRICT +); diff --git a/migrations/20230324225513_create_players.down.sql b/migrations/20230324225513_create_players.down.sql new file mode 100644 index 0000000..9616315 --- /dev/null +++ b/migrations/20230324225513_create_players.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE players; diff --git a/migrations/20230324225513_create_players.up.sql b/migrations/20230324225513_create_players.up.sql new file mode 100644 index 0000000..16be6f3 --- /dev/null +++ b/migrations/20230324225513_create_players.up.sql @@ -0,0 +1,7 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS players ( + id SERIAL PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + height_cm INTEGER, + weight_kg INTEGER +); diff --git a/migrations/20230324230201_create_games.down.sql b/migrations/20230324230201_create_games.down.sql new file mode 100644 index 0000000..b713899 --- /dev/null +++ b/migrations/20230324230201_create_games.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE games; diff --git a/migrations/20230324230201_create_games.up.sql b/migrations/20230324230201_create_games.up.sql new file mode 100644 index 0000000..b7a03ac --- /dev/null +++ b/migrations/20230324230201_create_games.up.sql @@ -0,0 +1,17 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS games ( + id SERIAL PRIMARY KEY NOT NULL, + -- a possibly null name for the game; this allows there to be special names like "Gold Medal Game" + name VARCHAR(255), + team_home INTEGER NOT NULL, + team_away INTEGER NOT NULL, + -- home and away teams need to actually be teams + CONSTRAINT team_home_fk + FOREIGN KEY(team_home) + REFERENCES teams(id) + ON DELETE RESTRICT, + CONSTRAINT team_away_fk + FOREIGN KEY(team_away) + REFERENCES teams(id) + ON DELETE RESTRICT +); diff --git a/migrations/20230325035659_add_leagues.down.sql b/migrations/20230325035659_add_leagues.down.sql new file mode 100644 index 0000000..6950571 --- /dev/null +++ b/migrations/20230325035659_add_leagues.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DELETE FROM leagues WHERE id=1; diff --git a/migrations/20230325035659_add_leagues.up.sql b/migrations/20230325035659_add_leagues.up.sql new file mode 100644 index 0000000..e51c111 --- /dev/null +++ b/migrations/20230325035659_add_leagues.up.sql @@ -0,0 +1,5 @@ +-- Add up migration script here +INSERT INTO leagues + (id, name, start_date, end_date) +VALUES + (1, '2022 Canadian National Blind Hockey Tournament', '2022-03-24', '2022-03-26'); diff --git a/migrations/20230325040553_add_divisions.down.sql b/migrations/20230325040553_add_divisions.down.sql new file mode 100644 index 0000000..e726f4d --- /dev/null +++ b/migrations/20230325040553_add_divisions.down.sql @@ -0,0 +1,2 @@ +DELETE FROM divisions + WHERE id BETWEEN 1 AND 3; diff --git a/migrations/20230325040553_add_divisions.up.sql b/migrations/20230325040553_add_divisions.up.sql new file mode 100644 index 0000000..d92c82e --- /dev/null +++ b/migrations/20230325040553_add_divisions.up.sql @@ -0,0 +1,6 @@ +INSERT INTO divisions + (id, name, league) +VALUES + (1, 'Low Vision & Development Division', 1), + (2, 'Open Division', 1), + (3, 'Children Division', 1); diff --git a/migrations/20230325040554_add_teams.down.sql b/migrations/20230325040554_add_teams.down.sql new file mode 100644 index 0000000..b920d1e --- /dev/null +++ b/migrations/20230325040554_add_teams.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DELETE FROM teams WHERE id=1 OR id=2; diff --git a/migrations/20230325040554_add_teams.up.sql b/migrations/20230325040554_add_teams.up.sql new file mode 100644 index 0000000..c9a7a9f --- /dev/null +++ b/migrations/20230325040554_add_teams.up.sql @@ -0,0 +1,6 @@ +-- Add up migration script here +INSERT INTO teams + (id, name, division) +VALUES + (1, 'Bullseye', 1), + (2, 'See Cats', 1); diff --git a/migrations/20230325044408_populate_players.down.sql b/migrations/20230325044408_populate_players.down.sql new file mode 100644 index 0000000..2fcc897 --- /dev/null +++ b/migrations/20230325044408_populate_players.down.sql @@ -0,0 +1,3 @@ +-- Add down migration script here +DELETE FROM players + WHERE id BETWEEN 1 AND 31; diff --git a/migrations/20230325044408_populate_players.up.sql b/migrations/20230325044408_populate_players.up.sql new file mode 100644 index 0000000..3a8578a --- /dev/null +++ b/migrations/20230325044408_populate_players.up.sql @@ -0,0 +1,35 @@ +-- Add up migration script here +INSERT INTO players + (id, name) +VALUES + (1, 'Tait Hoyem'), + (2, 'Hillary Scanlon'), + (3, 'Nelson Rego'), + (4, 'Carrie Anton'), + (5, 'Salamaan Chaudhri'), + (6, 'Ben Ho Lung'), + (7, 'Brian MacLean'), + (8, 'Shannon Murphy'), + (9, 'Joseph Robinson'), + (10, 'Drexcyl Sison'), + (11, 'Ginny Sweet'), + (12, 'Catharine Lemay'), + (13, 'Thomas Stewart'), + (14, 'Maurice Clement-Lafrance'), + (15, 'Jennifer Fancy'), + (16, 'Allyssa Foulds'), + (17, 'Ryan Kucy'), + (18, 'Denis LeBlanc'), + (19, 'Bob Lowe'), + (20, 'Ted Moritsugu'), + (21, 'Dave Poidevin'), + (22, 'Jillian Stewart'), + (23, 'Laura Mark'), + (24, 'Matt Arnold'), + (25, 'Rory Kucy'), + (26, 'Jeff Stewart'), + (27, 'Dylan Brown'), + (28, 'Codi Isaac'), + (29, 'Richard Isaac'), + (30, 'Tyler McGuffin'), + (31, 'Scarlette Dorn'); diff --git a/migrations/20230325193929_create_positions.down.sql b/migrations/20230325193929_create_positions.down.sql new file mode 100644 index 0000000..1f1c863 --- /dev/null +++ b/migrations/20230325193929_create_positions.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS positions; diff --git a/migrations/20230325193929_create_positions.up.sql b/migrations/20230325193929_create_positions.up.sql new file mode 100644 index 0000000..0365918 --- /dev/null +++ b/migrations/20230325193929_create_positions.up.sql @@ -0,0 +1,9 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS positions ( + id SERIAL PRIMARY KEY NOT NULL, + name VARCHAR(32) NOT NULL, + -- the short version, which should usually one character can be 2 charaters in some rare cases. + -- for example, in Goalball you'd have L, R, and C. + -- In hockey, you'd have C, D, LW and RW. + short_name VARCHAR(2) NOT NULL +); diff --git a/migrations/20230325194303_add_positions.down.sql b/migrations/20230325194303_add_positions.down.sql new file mode 100644 index 0000000..b29fbb5 --- /dev/null +++ b/migrations/20230325194303_add_positions.down.sql @@ -0,0 +1,3 @@ +-- Add down migration script here +DELETE FROM positions + WHERE id BETWEEN 1 AND 7; diff --git a/migrations/20230325194303_add_positions.up.sql b/migrations/20230325194303_add_positions.up.sql new file mode 100644 index 0000000..ccbff8e --- /dev/null +++ b/migrations/20230325194303_add_positions.up.sql @@ -0,0 +1,11 @@ +-- Add up migration script here +INSERT INTO positions + (id, name, short_name) +VALUES + (1, 'Center', 'C'), + (2, 'Right-Wing', 'R'), + (3, 'Left-Wing', 'L'), + (4, 'Defence', 'D'), + (5, 'Goalie', 'G'), + (6, 'Head Coach', 'HC'), + (7, 'Assistant Coach', 'AC'); diff --git a/migrations/20230327021921_create_periods.down.sql b/migrations/20230327021921_create_periods.down.sql new file mode 100644 index 0000000..6e9fcb7 --- /dev/null +++ b/migrations/20230327021921_create_periods.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS periods; diff --git a/migrations/20230327021921_create_periods.up.sql b/migrations/20230327021921_create_periods.up.sql new file mode 100644 index 0000000..ec99691 --- /dev/null +++ b/migrations/20230327021921_create_periods.up.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS periods ( + id SERIAL PRIMARY KEY NOT NULL, + -- "first", "second", "third", "second overtime", "shootout" + name VARCHAR(32) NOT NULL, + -- "1", "2", "3", "OT", "[2-9]OT", "SO" + -- technically 10+OT would not work, but this should be rare enough to not worry about. + short_name VARCHAR(3) NOT NULL +); diff --git a/migrations/20230327021922_add_periods.down.sql b/migrations/20230327021922_add_periods.down.sql new file mode 100644 index 0000000..3035fb5 --- /dev/null +++ b/migrations/20230327021922_add_periods.down.sql @@ -0,0 +1 @@ +DELETE FROM periods; diff --git a/migrations/20230327021922_add_periods.up.sql b/migrations/20230327021922_add_periods.up.sql new file mode 100644 index 0000000..41aeb7d --- /dev/null +++ b/migrations/20230327021922_add_periods.up.sql @@ -0,0 +1,16 @@ +INSERT INTO periods + (id, name, short_name) +VALUES + (1, 'first', '1'), + (2, 'second', '2'), + (3, 'third', '3'), + (4, 'overtime', 'OT'), + (5, 'shootout', 'SO'), + (6, 'second overtime', '2OT'), + (7, 'third overtime', '3OT'), + (8, 'fourth overtime', '4OT'), + (9, 'fifth overtime', '5OT'), + (10, 'sixth overtime', '6OT'), + (11, 'seventh overtime', '7OT'), + (12, 'eighth overtime', '8OT'), + (13, 'ninth overtime', '9OT'); diff --git a/migrations/20230327024927_create_team_players.down.sql b/migrations/20230327024927_create_team_players.down.sql new file mode 100644 index 0000000..a99de3f --- /dev/null +++ b/migrations/20230327024927_create_team_players.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS team_players; diff --git a/migrations/20230327024927_create_team_players.up.sql b/migrations/20230327024927_create_team_players.up.sql new file mode 100644 index 0000000..f2e3bef --- /dev/null +++ b/migrations/20230327024927_create_team_players.up.sql @@ -0,0 +1,21 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS team_players ( + id SERIAL PRIMARY KEY NOT NULL, + team INTEGER NOT NULL, + player INTEGER NOT NULL, + position INTEGER NOT NULL, + -- not a foreign key + player_number INTEGER NOT NULL, + CONSTRAINT team_fk + FOREIGN KEY(team) + REFERENCES teams(id) + ON DELETE RESTRICT, + CONSTRAINT player_fk + FOREIGN KEY(player) + REFERENCES players(id) + ON DELETE RESTRICT, + CONSTRAINT position_fk + FOREIGN KEY(position) + REFERENCES positions(id) + ON DELETE RESTRICT +); diff --git a/migrations/20230327025719_add_team_players.down.sql b/migrations/20230327025719_add_team_players.down.sql new file mode 100644 index 0000000..0fa63d9 --- /dev/null +++ b/migrations/20230327025719_add_team_players.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DELETE FROM team_players; diff --git a/migrations/20230327025719_add_team_players.up.sql b/migrations/20230327025719_add_team_players.up.sql new file mode 100644 index 0000000..a39eaf7 --- /dev/null +++ b/migrations/20230327025719_add_team_players.up.sql @@ -0,0 +1,178 @@ +-- Add up migration script here +INSERT INTO team_players + (team, player, position, player_number) +VALUES + ( + 1, + 31, + 1, + 11 + ), + ( + 1, + 1, + 3, + 3 + ), + ( + 1, + 2, + 4, + 8 + ), + ( + 1, + 3, + 5, + 1 + ), + ( + 1, + 4, + 2, + 14 + ), + ( + 1, + 5, + 4, + 91 + ), + ( + 1, + 7, + 1, + 15 + ), + ( + 1, + 8, + 4, + 10 + ), + ( + 1, + 9, + 3, + 13 + ), + ( + 1, + 10, + 1, + 10 + ), + ( + 1, + 11, + 2, + 84 + ), + ( + 2, + 12, + 5, + 35 + ), + ( + 2, + 13, + 5, + 30 + ), + ( + 2, + 14, + 1, + 15 + ), + ( + 2, + 15, + 2, + 17 + ), + ( + 2, + 16, + 1, + 3 + ), + ( + 2, + 17, + 2, + 9 + ), + ( + 2, + 18, + 4, + 16 + ), + ( + 2, + 19, + 4, + 4 + ), + ( + 2, + 21, + 4, + 14 + ), + ( + 2, + 22, + 4, + 12 + ), + ( + 2, + 23, + 2, + 10 + ), + ( + 2, + 24, + 7, + 0 + ), + ( + 2, + 25, + 7, + 0 + ), + ( + 2, + 26, + 7, + 0 + ), + ( + 1, + 27, + 7, + 0 + ), + ( + 1, + 28, + 7, + 0 + ), + ( + 1, + 29, + 7, + 0 + ), + ( + 1, + 30, + 7, + 0 + ); diff --git a/migrations/20230327030604_add_games.down.sql b/migrations/20230327030604_add_games.down.sql new file mode 100644 index 0000000..c1170d1 --- /dev/null +++ b/migrations/20230327030604_add_games.down.sql @@ -0,0 +1,2 @@ +DELETE FROM games + WHERE id BETWEEN 1 AND 4; diff --git a/migrations/20230327030604_add_games.up.sql b/migrations/20230327030604_add_games.up.sql new file mode 100644 index 0000000..556f7f9 --- /dev/null +++ b/migrations/20230327030604_add_games.up.sql @@ -0,0 +1,27 @@ +INSERT INTO games + (id, name, team_home, team_away) +VALUES + ( + 1, + 'Game 1', + 1, -- Bullseye + 2 -- Seecats + ), + ( + 2, + 'Game 2', + 1, -- Bullseye + 2 -- Seecats + ), + ( + 3, + 'Game 3', + 1, -- Bullseye + 2 -- Seecats + ), + ( + 4, + 'Game 4', + 1, -- Bullseye + 2 -- Seecats + ); diff --git a/migrations/20230327224840_create_shots.down.sql b/migrations/20230327224840_create_shots.down.sql new file mode 100644 index 0000000..1cbb304 --- /dev/null +++ b/migrations/20230327224840_create_shots.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS shots; diff --git a/migrations/20230327224840_create_shots.up.sql b/migrations/20230327224840_create_shots.up.sql new file mode 100644 index 0000000..496b1a3 --- /dev/null +++ b/migrations/20230327224840_create_shots.up.sql @@ -0,0 +1,68 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS shots ( + id SERIAL PRIMARY KEY NOT NULL, + + -- video timestampt if known; seconds offset from beginning of video + video_timestamp INTEGER, + -- player that blocked the shot, if applicable + blocker INTEGER, + -- on net; did it go towards the goalie (this does not say whether it went in or not) + on_net BOOLEAN NOT NULL, + -- did the puck go in? + goal BOOLEAN NOT NULL, + -- what team was the shooter on + shooter_team INTEGER NOT NULL, + -- which player is the shooter + shooter INTEGER NOT NULL, + -- which player was the goalie + goalie INTEGER NOT NULL, + -- which game was this a part of + game INTEGER NOT NULL, + -- which period did the shot happen in + period INTEGER NOT NULL, + -- when did the shot happen relative to the beginning of the period + period_time INTEGER NOT NULL, + -- if applicable, set assistant(s) + assistant INTEGER, + assistant_second INTEGER, + -- was the shooter a real player + CONSTRAINT shooter_fk + FOREIGN KEY(shooter) + REFERENCES players(id) + ON DELETE RESTRICT, + -- was the assistant is a real player + CONSTRAINT assistant_fk + FOREIGN KEY(assistant) + REFERENCES players(id) + ON DELETE RESTRICT, + -- was the second assistant a real player + CONSTRAINT assistant_second_fk + FOREIGN KEY(assistant_second) + REFERENCES players(id) + ON DELETE RESTRICT, + -- was the goalie a real player + CONSTRAINT goalie_fk + FOREIGN KEY(goalie) + REFERENCES players(id) + ON DELETE RESTRICT, + -- was the (optional) blocker a real player + CONSTRAINT blocker_fk + FOREIGN KEY(blocker) + REFERENCES players(id) + ON DELETE RESTRICT, + -- was the shooter's team a real team + CONSTRAINT shooter_team_fk + FOREIGN KEY(shooter_team) + REFERENCES teams(id) + ON DELETE RESTRICT, + -- is the game a real game + CONSTRAINT game_fk + FOREIGN KEY(game) + REFERENCES games(id) + ON DELETE RESTRICT, + -- is the period refgerences a real period type + CONSTRAINT period_fk + FOREIGN KEY(period) + REFERENCES periods(id) + ON DELETE RESTRICT +); diff --git a/migrations/20230327235843_add_shots.down.sql b/migrations/20230327235843_add_shots.down.sql new file mode 100644 index 0000000..80763cd --- /dev/null +++ b/migrations/20230327235843_add_shots.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DELETE FROM shots; diff --git a/migrations/20230327235843_add_shots.up.sql b/migrations/20230327235843_add_shots.up.sql new file mode 100644 index 0000000..3337f91 --- /dev/null +++ b/migrations/20230327235843_add_shots.up.sql @@ -0,0 +1,186 @@ +-- Add up migration script here +INSERT INTO shots + (shooter_team, goalie, shooter, game, period, period_time, video_timestamp, assistant, assistant_second, on_net, goal) +VALUES + ( + 2, + 3, + 14, + 1, + 3, + 503, + null, + 16, + null, + true, + true + ), + ( + 1, + 12, + 7, + 1, + 3, + 26, + null, + 1, + null, + true, + true + ), + ( + 1, + 13, + 31, + 2, + 2, + 1186, + 1649, + 2, + null, + true, + true + ), + ( + 2, + 3, + 22, + 3, + 1, + 657, + 1268, + 21, + null, + true, + true + ), + ( + 1, + 13, + 2, + 3, + 1, + 565, + 1360, + 7, + null, + true, + true + ), + ( + 1, + 12, + 1, + 3, + 3, + 282, + 3918, + 1, + null, + true, + true + ), + ( + 2, + 3, + 18, + 4, + 1, + 691, + 663, + 1, + null, + true, + true + ), + ( + 1, + 12, + 2, + 4, + 1, + 106, + 1247, + 31, + null, + true, + true + ), + ( + 1, + 13, + 2, + 4, + 2, + 883, + 1862, + 7, + null, + true, + true + ), + ( + 1, + 13, + 2, + 4, + 2, + 613, + 2132, + 1, + null, + true, + true + ), + ( + 1, + 13, + 2, + 4, + 2, + 514, + 2231, + 31, + null, + true, + true + ), + ( + 2, + 3, + 14, + 4, + 3, + 1193, + 2934, + 16, + null, + true, + true + ), + ( + 2, + 3, + 16, + 4, + 3, + 972, + 3154, + 14, + null, + true, + true + ), + ( + 2, + 3, + 22, + 4, + 3, + 16, + 4232, + 16, + null, + true, + true + ); diff --git a/migrations/20230328002755_add_stats_proc.down.sql b/migrations/20230328002755_add_stats_proc.down.sql new file mode 100644 index 0000000..abca983 --- /dev/null +++ b/migrations/20230328002755_add_stats_proc.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP FUNCTION IF EXISTS player_stats_overview_all; diff --git a/migrations/20230328002755_add_stats_proc.up.sql b/migrations/20230328002755_add_stats_proc.up.sql new file mode 100644 index 0000000..be5fe7b --- /dev/null +++ b/migrations/20230328002755_add_stats_proc.up.sql @@ -0,0 +1,29 @@ +-- Add up migration script here +CREATE OR REPLACE FUNCTION player_stats_overview_all() RETURNS VOID +LANGUAGE SQL +AS $$ + SELECT + ( + SELECT COUNT(id) + FROM shots + WHERE shooter=players.id + AND goal=true + ) AS goals, + ( + SELECT COUNT(id) + FROM shots + WHERE assistant=players.id + AND goal=true + ) AS assists, + ( + SELECT COUNT(id) + FROM shots + WHERE assistant=players.id + OR shooter=players.id + ) AS points, + players.name AS player_name + FROM players + ORDER BY + points DESC, + players.name; +$$; diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..0ed89d8 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,9 @@ +use sqlx::{Postgres, Pool}; +use sqlx::postgres::PgPoolOptions; + +pub async fn connect() -> Pool { + PgPoolOptions::new() + .max_connections(8) + .connect("postgres://ibihf2:ibihf@localhost/ibihf").await + .unwrap() +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ff17305 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,171 @@ +mod db; +mod model; + +use crate::model::{ + TableName, + League, + Team, + Division, + TeamPlayer, + Player, + Shot, +}; + +use sqlx::{ + Postgres, + Pool, +}; +use axum::{ + Router, + http::StatusCode, + extract::{ + Path, + State, + }, + response::{ + Json, + IntoResponse, + }, + routing::get, +}; +use axum_macros::debug_handler; +use std::net::SocketAddr; +use std::sync::Arc; + +#[derive(Clone)] +pub struct ServerState { + db_pool: Arc>, +} + +#[tokio::main] +async fn main() { + let pool = db::connect().await; + let state = ServerState { + db_pool: Arc::new(pool), + }; + let router = Router::new() + .route("/league/", get(league_all)) + .route("/league/:id", get(league_id)) + .route("/division/", get(division_all)) + .route("/division/:id", get(division_id)) + .route("/team/", get(team_all)) + .route("/team/:id", get(team_id)) + .route("/player/", get(player_all)) + .route("/player/:id", get(player_id)) + .route("/team-player/", get(team_player_all)) + .route("/team-playerplayer/:id", get(team_player_id)) + .route("/shot/", get(shots_all)) + .route("/shot/:id", get(shots_id)) + .with_state(state); + let addr = SocketAddr::from(([127, 0, 0, 1], 8000)); + println!("Listening on {}", addr); + axum::Server::bind(&addr) + .serve(router.into_make_service()) + .await + .unwrap(); +} + + +async fn get_all sqlx::FromRow<'r, sqlx::postgres::PgRow>>(pool: &sqlx::PgPool) -> Result, sqlx::Error> { + sqlx::query_as::<_, T>( + &format!("SELECT * FROM {};", ::TABLE_NAME) + ) + .fetch_all(pool) + .await +} +async fn get_by_id sqlx::FromRow<'r, sqlx::postgres::PgRow>>(pool: &sqlx::PgPool, id: i32) -> Result, sqlx::Error> { + sqlx::query_as::<_, T>( + &format!("SELECT * FROM {} WHERE id = $1;", ::TABLE_NAME) + ) + .bind(id) + .fetch_optional(pool) + .await +} +/* +async fn insert_into sqlx::FromRow<'r, sqlx::postgres::PgRow>>(pool: &sqlx::PgPool, new: &T) -> Result { + let query = sql_builder::SqlBuilder::insert_into(::TABLE_NAME) + .values(()) + .sql().unwrap(); + sqlx::query( + &query + ) + .execute(pool) + .await +} +*/ + +macro_rules! get_all { + ($crud_struct:ident, $func_name:ident) => { + #[debug_handler] + async fn $func_name(State(server_config): State) -> impl IntoResponse { + let cruder = get_all::<$crud_struct>(&server_config.db_pool) + .await + .unwrap(); + (StatusCode::OK, Json(cruder)) + } + } +} +macro_rules! get_by_id { + ($crud_struct:ident, $func_name:ident) => { + #[debug_handler] + async fn $func_name(State(server_config): State, Path(id): Path) -> impl IntoResponse { + let cruder = get_by_id::<$crud_struct>(&server_config.db_pool, id) + .await + .unwrap(); + (StatusCode::OK, Json(cruder)) + } + } +} + +/* +macro_rules! insert { + ($crud_struct:ident, $func_name:ident) => { + #[debug_handler] + async fn $func_name(State(server_config): State, Json(NewPlayer): Json) -> impl IntoResponse { + let cruder = get_by_id::<$crud_struct>(&server_config.db_pool, id) + .await + .unwrap(); + (StatusCode::OK, Json(cruder)) + } + } +} +*/ + +macro_rules! impl_all_query_types { + ($ty:ident, $func_all:ident, $func_by_id:ident) => { + get_all!($ty, $func_all); + get_by_id!($ty, $func_by_id); + } +} + +impl_all_query_types!( + TeamPlayer, + team_player_all, + team_player_id +); +impl_all_query_types!( + Player, + player_all, + player_id +); +impl_all_query_types!( + Team, + team_all, + team_id +); +impl_all_query_types!( + Shot, + shots_all, + shots_id +); +impl_all_query_types!( + Division, + division_all, + division_id +); +impl_all_query_types!( + League, + league_all, + league_id +); + diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..31b4ce2 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,261 @@ +use sqlx::FromRow; +use sqlx::PgPool; +use sqlx::types::chrono::{DateTime, Utc}; +use chrono::serde::{ts_seconds, ts_seconds_option}; +use serde::{Serialize, Deserialize}; + +pub trait TableName { + const TABLE_NAME: &'static str; +} +macro_rules! impl_table_name { + ($ty:ident, $tname:expr) => { + impl TableName for $ty { + const TABLE_NAME: &'static str = $tname; + } + } +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct League { + pub id: i32, + pub name: String, + #[serde(with = "ts_seconds")] + pub start_date: DateTime, + #[serde(with = "ts_seconds_option")] + pub end_date: Option>, +} +#[derive(FromRow, Serialize, Deserialize)] +pub struct NewLeague { + pub name: String, + #[serde(with = "ts_seconds")] + pub start_date: DateTime, + #[serde(with = "ts_seconds_option")] + pub end_date: Option>, +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct Division { + pub id: i32, + pub name: String, + pub league: i32, +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct NewDivision { + pub id: i32, + pub name: String, + pub league: i32, +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct Team { + pub id: i32, + pub name: String, + pub division: i32, +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct NewTeam { + pub name: String, + pub division: i32, +} + +#[derive(FromRow, Serialize, Deserialize)] +pub struct Player { + pub id: i32, + pub name: String, + pub weight_kg: Option, + pub height_cm: Option, +} + +#[derive(FromRow, Deserialize, Serialize)] +pub struct NewPlayer { + pub name: String, + pub weight_kg: Option, + pub height_cm: Option, +} + +#[derive(FromRow, Deserialize, Serialize)] +pub struct Shot { + pub id: i32, + pub shooter_team: i32, + pub goalie: i32, + pub assistant: Option, + pub game: i32, + pub period: i32, + pub period_time: i32, + pub video_timestamp: Option, +} + +#[derive(FromRow, Deserialize, Serialize)] +pub struct TeamPlayer { + pub id: i32, + pub team: i32, + pub player: i32, + pub position: i32, +} + +#[derive(FromRow, Deserialize, Serialize, Debug)] +pub struct Notification { + pub scorer_name: String, + pub scorer_number: i32, + pub position: String, + pub scorer_team_name: String, + pub period_name: String, + pub period_time_left: i32, +} + +#[derive(FromRow, Deserialize, Serialize, Debug)] +pub struct PlayerStats { + pub player_name: String, + pub goals: i64, + pub assists: i64, + pub points: i64, +} + +async fn get_player_stats_overview(pool: PgPool) -> Result, sqlx::Error> { + let query = r#" +SELECT + ( + SELECT COUNT(id) + FROM shots + WHERE shooter=players.id + AND goal=true + ) AS goals, + ( + SELECT COUNT(id) + FROM shots + WHERE assistant=players.id + AND goal=true + ) AS assists, + ( + SELECT COUNT(id) + FROM shots + WHERE assistant=players.id + OR shooter=players.id + ) AS points, + players.name AS player_name +FROM players +ORDER BY + points DESC, + players.name; +"#; + let result = sqlx::query_as::<_, PlayerStats>(query) + .fetch_all(&pool) + .await; + result +} + +impl_table_name!(TeamPlayer, "team_players"); +impl_table_name!(Player, "players"); +impl_table_name!(League, "leagues"); +impl_table_name!(Division, "divisions"); +impl_table_name!(Team, "teams"); +impl_table_name!(Shot, "shots"); + +#[cfg(test)] +mod tests { + use std::env; + use crate::model::{ + TeamPlayer, + Player, + League, + Division, + Team, + Shot, + TableName, + Notification, + get_player_stats_overview, + }; + + #[test] + fn check_player_overall_stats() { + tokio_test::block_on(async move { + let pool = db_connect().await; + let players_stats = get_player_stats_overview(pool).await.unwrap(); + for player_stats in players_stats { + println!("{player_stats:?}"); + } + }) + } + + #[test] + fn check_notification_query() { + tokio_test::block_on(async move { + let pool = db_connect().await; + let query = r#" +SELECT + teams.name AS scorer_team_name, + players.name AS scorer_name, + positions.name AS position, + team_players.player_number AS scorer_number, + shots.period_time AS period_time_left, + periods.name AS period_name +FROM + shots +JOIN teams ON teams.id=shots.shooter_team +JOIN players ON players.id=shots.shooter +JOIN team_players ON team_players.player=players.id AND team_players.team=teams.id +JOIN periods ON periods.id=shots.period +JOIN positions ON positions.id=team_players.position; +"#; + let result = sqlx::query_as::<_, Notification>(query) + .fetch_one(&pool) + .await + .unwrap(); + let minutes = result.period_time_left / 60; + let seconds = result.period_time_left % 60; + println!("{0} {1} player #{3} {2} has scored! Time of the goal: {4}:{5} in the {6}", + result.scorer_team_name, + result.position, + result.scorer_name, + result.scorer_number, + minutes, + seconds, + result.period_name + ); + }); + } + + /// A simple function to connect to the database. + async fn db_connect() -> sqlx::PgPool { + let db_url = env::var("DATABASE_URL").expect("DATABASE_URL environment variable must be set to run tests."); + sqlx::postgres::PgPoolOptions::new() + .max_connections(1) + .connect(&db_url) + .await + .expect("Active database connection must be made") + } + + /// This macro generates a test that will `SELECT` all records for a table. + /// Then, it checks that + /// 1. The table rows gets deserialized correctly. + /// 2. There is at least one row. + macro_rules! generate_select_test { + ($ret_type:ident, $func_name:ident) => { + #[test] + fn $func_name() { + tokio_test::block_on(async move { + let pool = db_connect().await; + let results = sqlx::query_as::<_, $ret_type>( + &format!( + "SELECT * FROM {};", + <$ret_type as TableName>::TABLE_NAME + ) + ) + .fetch_all(&pool) + .await + .unwrap(); + // check that there is at least one result item + assert!(results.len() > 0, "There must be at least one result in the table."); + }); + } + } + } + generate_select_test!(TeamPlayer, select_team_player); + generate_select_test!(Player, select_player); + generate_select_test!(League, select_league); + generate_select_test!(Division, select_division); + generate_select_test!(Team, select_team); + generate_select_test!(Shot, select_shot); +}