diff --git a/Cargo.lock b/Cargo.lock index 4136fa1..8dee183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,17 +17,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.11" @@ -152,7 +141,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -164,7 +153,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", "synstructure", ] @@ -176,7 +165,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -187,14 +176,14 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] @@ -239,7 +228,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.2", "tokio", - "tower 0.5.1", + "tower", "tower-layer", "tower-service", "tracing", @@ -287,12 +276,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -316,6 +299,9 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "blake2" @@ -421,10 +407,10 @@ version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -440,10 +426,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] -name = "const-oid" -version = "0.7.1" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] [[package]] name = "const-oid" @@ -469,9 +458,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -506,16 +495,6 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array 0.14.7", - "subtle", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -562,7 +541,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -575,7 +554,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -597,7 +576,7 @@ dependencies = [ "pollster", "serde", "serde_json", - "thiserror", + "thiserror 2.0.3", "x509-cert", "x509-parser", ] @@ -614,7 +593,7 @@ dependencies = [ "ddnet-accounts-types", "either", "email_address", - "parking_lot 0.12.3", + "parking_lot", "serde", "serde_json", "tempfile", @@ -645,7 +624,7 @@ dependencies = [ "ddnet-accounts-shared", "ddnet-accounts-types", "sqlx", - "thiserror", + "thiserror 2.0.3", "tokio", ] @@ -655,6 +634,7 @@ version = "0.2.0" dependencies = [ "anyhow", "async-trait", + "futures", "sqlx", ] @@ -675,7 +655,7 @@ dependencies = [ "ddnet-account-sql", "ddnet-accounts-shared", "ddnet-accounts-types", - "der 0.7.9", + "der", "ecdsa", "ed25519-dalek", "either", @@ -688,7 +668,7 @@ dependencies = [ "log", "notify", "p256", - "parking_lot 0.12.3", + "parking_lot", "rand", "rcgen", "regex", @@ -700,7 +680,7 @@ dependencies = [ "strum", "tempfile", "tokio", - "tower 0.4.13", + "tower", "tower_governor", "url", "x509-cert", @@ -713,9 +693,9 @@ dependencies = [ "anyhow", "argon2", "chrono", - "const-oid 0.9.6", + "const-oid", "ddnet-accounts-types", - "der 0.7.9", + "der", "ecdsa", "ed25519-dalek", "email_address", @@ -726,9 +706,9 @@ dependencies = [ "rand", "rcgen", "serde", - "spki 0.7.3", + "spki", "strum", - "thiserror", + "thiserror 2.0.3", "url", "x509-cert", ] @@ -737,27 +717,16 @@ dependencies = [ name = "ddnet-accounts-types" version = "0.1.0" -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid 0.7.1", - "crypto-bigint 0.3.2", - "pem-rfc7468 0.3.1", -] - [[package]] name = "der" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ - "const-oid 0.9.6", + "const-oid", "der_derive", "flagset", - "pem-rfc7468 0.7.0", + "pem-rfc7468", "zeroize", ] @@ -783,7 +752,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -802,7 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid 0.9.6", + "const-oid", "crypto-common", "subtle", ] @@ -815,7 +784,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -830,12 +799,12 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.9", + "der", "digest", "elliptic-curve", "rfc6979", "signature", - "spki 0.7.3", + "spki", ] [[package]] @@ -844,7 +813,7 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8 0.10.2", + "pkcs8", "serde", "signature", ] @@ -869,6 +838,9 @@ name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] [[package]] name = "elliptic-curve" @@ -877,13 +849,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", - "crypto-bigint 0.5.5", + "crypto-bigint", "digest", "ff", "generic-array 0.14.7", "group", - "pem-rfc7468 0.7.0", - "pkcs8 0.10.2", + "pem-rfc7468", + "pkcs8", "rand_core", "sec1", "subtle", @@ -896,7 +868,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60d1d33cdaede7e24091f039632eb5d3c7469fe5b066a985281a34fc70fa317f" dependencies = [ - "base64 0.22.1", + "base64", "memchr", ] @@ -957,11 +929,27 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" -version = "2.5.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "fastrand" @@ -1005,14 +993,13 @@ checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec" [[package]] name = "flume" -version = "0.10.14" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", - "pin-project", - "spin 0.9.8", + "spin", ] [[package]] @@ -1052,7 +1039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" dependencies = [ "nonempty", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1099,13 +1086,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -1122,7 +1109,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -1211,7 +1198,7 @@ dependencies = [ "futures-timer", "no-std-compat", "nonzero_ext", - "parking_lot 0.12.3", + "parking_lot", "portable-atomic", "quanta", "rand", @@ -1242,26 +1229,20 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.6.0", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash", "allocator-api2", ] @@ -1273,22 +1254,13 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.5.0" @@ -1301,6 +1273,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1310,6 +1291,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hostname" version = "0.4.0" @@ -1404,10 +1394,10 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.19", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", "tower-service", ] @@ -1584,7 +1574,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -1608,16 +1598,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.6.0" @@ -1630,9 +1610,9 @@ dependencies = [ [[package]] name = "inotify" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc" dependencies = [ "bitflags 1.3.2", "inotify-sys", @@ -1719,7 +1699,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -1728,7 +1708,7 @@ version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0161e452348e399deb685ba05e55ee116cae9410f4f51fe42d597361444521d9" dependencies = [ - "base64 0.22.1", + "base64", "chumsky", "email-encoding", "email_address", @@ -1755,9 +1735,9 @@ checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -1767,14 +1747,14 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall", ] [[package]] name = "libsqlite3-sys" -version = "0.24.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -1825,6 +1805,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1852,18 +1842,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "mio" version = "1.0.3" @@ -1871,6 +1849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.52.0", ] @@ -1922,9 +1901,9 @@ checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" [[package]] name = "notify" -version = "6.1.1" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009" dependencies = [ "bitflags 2.6.0", "filetime", @@ -1932,9 +1911,19 @@ dependencies = [ "kqueue", "libc", "log", - "mio 0.8.11", + "mio", + "notify-types", "walkdir", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "notify-types" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7393c226621f817964ffb3dc5704f9509e107a8b024b489cc2c1b217378785df" +dependencies = [ + "instant", ] [[package]] @@ -2047,7 +2036,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -2081,15 +2070,10 @@ dependencies = [ ] [[package]] -name = "parking_lot" -version = "0.11.2" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2098,21 +2082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[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 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2123,7 +2093,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -2151,19 +2121,10 @@ version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.22.1", + "base64", "serde", ] -[[package]] -name = "pem-rfc7468" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2196,7 +2157,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -2213,24 +2174,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" -dependencies = [ - "der 0.5.1", - "pkcs8 0.8.0", - "zeroize", -] - -[[package]] -name = "pkcs8" -version = "0.8.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.5.1", - "spki 0.5.4", - "zeroize", + "der", + "pkcs8", + "spki", ] [[package]] @@ -2239,8 +2189,8 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.9", - "spki 0.7.3", + "der", + "spki", ] [[package]] @@ -2251,9 +2201,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "pollster" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" [[package]] name = "portable-atomic" @@ -2379,21 +2329,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779" dependencies = [ "pem", - "ring 0.17.8", + "ring", "rustls-pki-types", "time", "yasna", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.7" @@ -2438,7 +2379,7 @@ version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "encoding_rs", "futures-core", @@ -2459,7 +2400,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", @@ -2485,21 +2426,6 @@ dependencies = [ "subtle", ] -[[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 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.8" @@ -2510,27 +2436,27 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rsa" -version = "0.6.1" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ - "byteorder", + "const-oid", "digest", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", - "pkcs8 0.8.0", + "pkcs8", "rand_core", - "smallvec", + "signature", + "spki", "subtle", "zeroize", ] @@ -2572,18 +2498,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" -dependencies = [ - "log", - "ring 0.16.20", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.23.19" @@ -2591,21 +2505,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -2627,9 +2533,9 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "ring 0.17.8", + "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -2668,16 +2574,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "sec1" version = "0.7.3" @@ -2685,9 +2581,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der 0.7.9", + "der", "generic-array 0.14.7", - "pkcs8 0.10.2", + "pkcs8", "subtle", "zeroize", ] @@ -2738,7 +2634,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -2827,6 +2723,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -2838,12 +2737,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -2862,16 +2755,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der 0.5.1", -] - [[package]] name = "spki" version = "0.7.3" @@ -2879,7 +2762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.9", + "der", "sha2", ] @@ -2895,95 +2778,203 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" dependencies = [ - "ahash 0.7.8", "atoi", - "bitflags 1.3.2", "byteorder", "bytes", "chrono", "crc", "crossbeam-queue", - "digest", - "dotenvy", "either", "event-listener", - "flume", "futures-channel", "futures-core", - "futures-executor", "futures-intrusive", + "futures-io", "futures-util", - "generic-array 0.14.7", + "hashbrown 0.14.5", "hashlink", "hex", - "indexmap 1.9.3", - "itoa", - "libc", - "libsqlite3-sys", + "indexmap", "log", "memchr", - "num-bigint", "once_cell", "paste", "percent-encoding", - "rand", - "rsa", - "rustls 0.20.9", - "rustls-pemfile 1.0.4", - "sha1", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", "sha2", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", + "thiserror 1.0.69", + "tokio", "tokio-stream", + "tracing", "url", "webpki-roots", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", + "hex", "once_cell", "proc-macro2", "quote", + "serde", + "serde_json", "sha2", "sqlx-core", - "sqlx-rt", - "syn 1.0.109", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ + "atoi", + "base64", + "bitflags 2.6.0", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array 0.14.7", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-rustls 0.23.4", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 1.0.69", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" +dependencies = [ + "atoi", + "base64", + "bitflags 2.6.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 1.0.69", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "tracing", + "url", ] [[package]] @@ -3037,11 +3028,11 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn", ] [[package]] @@ -3050,17 +3041,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[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.90" @@ -3095,7 +3075,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -3138,7 +3118,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -3149,7 +3138,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3226,7 +3226,7 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -3238,7 +3238,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "pin-project-lite", "socket2", "tokio-macros", @@ -3253,7 +3253,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -3266,24 +3266,13 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls 0.20.9", - "tokio", - "webpki", -] - [[package]] name = "tokio-rustls" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.19", + "rustls", "rustls-pki-types", "tokio", ] @@ -3312,17 +3301,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.1" @@ -3362,8 +3340,8 @@ dependencies = [ "governor", "http", "pin-project", - "thiserror", - "tower 0.5.1", + "thiserror 1.0.69", + "tower", "tracing", ] @@ -3387,7 +3365,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -3413,9 +3391,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" @@ -3434,15 +3412,9 @@ dependencies = [ [[package]] name = "unicode-properties" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode_categories" @@ -3450,12 +3422,6 @@ 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 = "untrusted" version = "0.9.0" @@ -3529,6 +3495,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.95" @@ -3551,7 +3523,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.90", + "syn", "wasm-bindgen-shared", ] @@ -3585,7 +3557,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3607,22 +3579,22 @@ dependencies = [ ] [[package]] -name = "webpki" -version = "0.22.4" +name = "webpki-roots" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "rustls-pki-types", ] [[package]] -name = "webpki-roots" -version = "0.22.6" +name = "whoami" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "webpki", + "redox_syscall", + "wasite", ] [[package]] @@ -3647,7 +3619,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3881,11 +3853,11 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" dependencies = [ - "const-oid 0.9.6", - "der 0.7.9", + "const-oid", + "der", "sha1", "signature", - "spki 0.7.3", + "spki", "tls_codec", ] @@ -3902,7 +3874,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -3935,7 +3907,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", "synstructure", ] @@ -3957,7 +3929,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -3977,7 +3949,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", "synstructure", ] @@ -3998,7 +3970,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] [[package]] @@ -4020,5 +3992,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index c13649f..eb87ee7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,7 @@ ddnet-account-sql = { version = "0.2.0", path = "lib/ddnet-account-sql", feature tokio = { version = "1.41.1", features = ["rt-multi-thread", "sync", "fs", "time", "macros"] } axum = "0.7.9" anyhow = { version = "1.0.93", features = ["backtrace"] } -# https://github.com/launchbadge/sqlx/issues/2636 -sqlx = { version = "=0.6.3", features = ["mysql", "any", "runtime-tokio-rustls", "chrono"] } +sqlx = { version = "0.8.2", features = ["mysql", "any", "runtime-tokio-rustls", "chrono"] } email_address = { version = "0.2.9", features = ["serde"] } ed25519-dalek = { version = "2.1.1", features = ["serde", "pkcs8"] } async-trait = "0.1.83" @@ -53,14 +52,14 @@ sha2 = { version = "0.10", features = ["oid"] } der = { version = "0.7.9", features = ["derive"] } chrono = { version = "0.4.38", features = ["serde"] } tower_governor = "0.4.3" -tower = "0.4.13" +tower = "0.5.1" strum = { version = "0.26.3", features = ["derive"] } reqwest = { version = "0.12.9" } hex = "0.4.3" iprange = "0.6.7" ipnet = "2.10.1" either = "1.13.0" -notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] } +notify = { version = "7.0.0", default-features = false, features = ["macos_kqueue"] } [dev-dependencies] ddnet-account-client = { version = "0.1.0", path = "lib/ddnet-account-client" } diff --git a/lib/ddnet-account-client/Cargo.toml b/lib/ddnet-account-client/Cargo.toml index 94e0c89..69e8474 100644 --- a/lib/ddnet-account-client/Cargo.toml +++ b/lib/ddnet-account-client/Cargo.toml @@ -15,11 +15,11 @@ async-trait = "0.1.83" email_address = { version = "0.2.9", features = ["serde"] } serde_json = "1.0.133" anyhow = { version = "1.0.93", features = ["backtrace"] } -thiserror = "1.0.69" +thiserror = "2.0.3" serde = { version = "1.0.215", features = ["derive"] } x509-parser = { version = "0.16.0", default-features = false } x509-cert = { version = "0.2.5" } hex = "0.4.3" [dev-dependencies] -pollster = "0.3.0" +pollster = "0.4.0" diff --git a/lib/ddnet-account-game-server/Cargo.toml b/lib/ddnet-account-game-server/Cargo.toml index d59a0ac..11cb73b 100644 --- a/lib/ddnet-account-game-server/Cargo.toml +++ b/lib/ddnet-account-game-server/Cargo.toml @@ -12,11 +12,10 @@ ddnet-accounts-types = { version = "0.1.0", path = "../ddnet-accounts-types" } ddnet-accounts-shared = { version = "0.1.0", path = "../ddnet-accounts-shared" } ddnet-account-sql = { version = "0.2.0", path = "../ddnet-account-sql", default-features = false } -# https://github.com/launchbadge/sqlx/issues/2636 -sqlx = { version = "=0.6.3", features = ["any", "runtime-tokio-rustls", "chrono"] } +sqlx = { version = "0.8.2", features = ["any", "runtime-tokio-rustls", "chrono"] } anyhow = { version = "1.0.93", features = ["backtrace"] } async-trait = "0.1.83" -thiserror = "1.0.69" +thiserror = "2.0.3" [dev-dependencies] tokio = { version = "1.41.1", features = ["rt-multi-thread", "sync", "fs", "time", "macros"] } diff --git a/lib/ddnet-account-game-server/src/auto_login.rs b/lib/ddnet-account-game-server/src/auto_login.rs index 7801337..c48b7f7 100644 --- a/lib/ddnet-account-game-server/src/auto_login.rs +++ b/lib/ddnet-account-game-server/src/auto_login.rs @@ -2,10 +2,9 @@ pub(crate) mod queries; use std::sync::Arc; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::game_server::user_id::UserId; use ddnet_accounts_types::account_id::AccountId; -use sqlx::Acquire; use thiserror::Error; use crate::shared::Shared; @@ -42,7 +41,7 @@ pub fn default_name(account_id: &AccountId) -> String { /// information to the account now. pub async fn auto_login( shared: Arc, - pool: &sqlx::AnyPool, + pool: &AnyPool, user_id: &UserId, ) -> anyhow::Result { if let Some(account_id) = &user_id.account_id { @@ -50,7 +49,7 @@ pub async fn auto_login( .acquire() .await .map_err(|err| AutoLoginError::Database(err.into()))?; - let con = pool_con + let mut con = pool_con .acquire() .await .map_err(|err| AutoLoginError::Database(err.into()))?; @@ -62,8 +61,8 @@ pub async fn auto_login( }; let res = qry - .query(con, &shared.db.register_user_statement) - .execute(&mut *con) + .query(&shared.db.register_user_statement) + .execute(&mut con) .await .map_err(|err| AutoLoginError::Database(err.into()))?; diff --git a/lib/ddnet-account-game-server/src/auto_login/queries.rs b/lib/ddnet-account-game-server/src/auto_login/queries.rs index 56c0c25..6c26045 100644 --- a/lib/ddnet-account-game-server/src/auto_login/queries.rs +++ b/lib/ddnet-account-game-server/src/auto_login/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use async_trait::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -20,16 +19,16 @@ pub struct RegisterUser<'a> { impl Query<()> for RegisterUser<'_> { #[cfg(feature = "mysql")] async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/try_insert_user.sql")) .await?) } #[cfg(feature = "sqlite")] async fn prepare_sqlite( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::sqlite::SqliteConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("sqlite/try_insert_user.sql")) .await?) @@ -37,8 +36,8 @@ impl Query<()> for RegisterUser<'_> { #[cfg(feature = "mysql")] fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let account_id = self.account_id; statement.query().bind(self.default_name).bind(account_id) @@ -46,13 +45,21 @@ impl Query<()> for RegisterUser<'_> { #[cfg(feature = "sqlite")] fn query_sqlite<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::sqlite::SqliteStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'b>> { let account_id = self.account_id; statement.query().bind(self.default_name).bind(account_id) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + #[cfg(feature = "mysql")] + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { + Err(anyhow!( + "Data rows are not supported for this query. + You probably want to check affected rows instead." + )) + } + #[cfg(feature = "sqlite")] + fn row_data_sqlite(_row: &sqlx::sqlite::SqliteRow) -> anyhow::Result<()> { Err(anyhow!( "Data rows are not supported for this query. You probably want to check affected rows instead." diff --git a/lib/ddnet-account-game-server/src/db.rs b/lib/ddnet-account-game-server/src/db.rs index a074068..394dfe7 100644 --- a/lib/ddnet-account-game-server/src/db.rs +++ b/lib/ddnet-account-game-server/src/db.rs @@ -1,4 +1,4 @@ -use sqlx::any::AnyStatement; +use ddnet_account_sql::any::AnyStatement; /// Shared data for a db connection pub struct DbConnectionShared { diff --git a/lib/ddnet-account-game-server/src/prepare.rs b/lib/ddnet-account-game-server/src/prepare.rs index 109d103..94f349b 100644 --- a/lib/ddnet-account-game-server/src/prepare.rs +++ b/lib/ddnet-account-game-server/src/prepare.rs @@ -1,25 +1,24 @@ use std::sync::Arc; -use ddnet_account_sql::query::Query; -use sqlx::Acquire; +use ddnet_account_sql::{any::AnyPool, query::Query}; use crate::{ auto_login::queries::RegisterUser, db::DbConnectionShared, rename::queries::RenameUser, shared::Shared, }; -async fn prepare_statements(pool: &sqlx::AnyPool) -> anyhow::Result { +async fn prepare_statements(pool: &AnyPool) -> anyhow::Result { let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; + let mut con = pool_con.acquire().await?; Ok(DbConnectionShared { - register_user_statement: RegisterUser::prepare(con).await?, - try_rename_statement: RenameUser::prepare(con).await?, + register_user_statement: RegisterUser::prepare(&mut con).await?, + try_rename_statement: RenameUser::prepare(&mut con).await?, }) } /// Prepare shared data used in the game server's implementation -pub async fn prepare(pool: &sqlx::AnyPool) -> anyhow::Result> { +pub async fn prepare(pool: &AnyPool) -> anyhow::Result> { Ok(Arc::new(Shared { db: prepare_statements(pool).await?, })) diff --git a/lib/ddnet-account-game-server/src/rename.rs b/lib/ddnet-account-game-server/src/rename.rs index 18668de..d6fb9d7 100644 --- a/lib/ddnet-account-game-server/src/rename.rs +++ b/lib/ddnet-account-game-server/src/rename.rs @@ -2,9 +2,8 @@ pub(crate) mod queries; use std::sync::Arc; -use ddnet_account_sql::{is_duplicate_entry, query::Query}; +use ddnet_account_sql::{any::AnyPool, is_duplicate_entry, query::Query}; use ddnet_accounts_shared::game_server::user_id::UserId; -use sqlx::Acquire; use thiserror::Error; use crate::{ @@ -39,7 +38,7 @@ pub enum RenameError { /// Returns `false` if the user had no account. pub async fn rename( shared: Arc, - pool: &sqlx::AnyPool, + pool: &AnyPool, user_id: &UserId, name: &str, ) -> anyhow::Result { @@ -65,7 +64,7 @@ pub async fn rename( .acquire() .await .map_err(|err| RenameError::Database(err.into()))?; - let con = pool_con + let mut con = pool_con .acquire() .await .map_err(|err| RenameError::Database(err.into()))?; @@ -73,8 +72,8 @@ pub async fn rename( let qry = RenameUser { account_id, name }; let res = qry - .query(con, &shared.db.try_rename_statement) - .execute(&mut *con) + .query(&shared.db.try_rename_statement) + .execute(&mut con) .await; if is_duplicate_entry(&res) { diff --git a/lib/ddnet-account-game-server/src/rename/queries.rs b/lib/ddnet-account-game-server/src/rename/queries.rs index 663655b..c252a97 100644 --- a/lib/ddnet-account-game-server/src/rename/queries.rs +++ b/lib/ddnet-account-game-server/src/rename/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use async_trait::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -20,16 +19,16 @@ pub struct RenameUser<'a> { impl Query<()> for RenameUser<'_> { #[cfg(feature = "mysql")] async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/try_rename.sql")) .await?) } #[cfg(feature = "sqlite")] async fn prepare_sqlite( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::sqlite::SqliteConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("sqlite/try_rename.sql")) .await?) @@ -37,8 +36,8 @@ impl Query<()> for RenameUser<'_> { #[cfg(feature = "mysql")] fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let account_id = self.account_id; statement.query().bind(self.name).bind(account_id) @@ -46,13 +45,21 @@ impl Query<()> for RenameUser<'_> { #[cfg(feature = "sqlite")] fn query_sqlite<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::sqlite::SqliteStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'b>> { let account_id = self.account_id; statement.query().bind(self.name).bind(account_id) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + #[cfg(feature = "mysql")] + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { + Err(anyhow!( + "Data rows are not supported for this query. + You probably want to check affected rows instead." + )) + } + #[cfg(feature = "sqlite")] + fn row_data_sqlite(_row: &sqlx::sqlite::SqliteRow) -> anyhow::Result<()> { Err(anyhow!( "Data rows are not supported for this query. You probably want to check affected rows instead." diff --git a/lib/ddnet-account-game-server/src/setup.rs b/lib/ddnet-account-game-server/src/setup.rs index 8cb0cb1..a92b222 100644 --- a/lib/ddnet-account-game-server/src/setup.rs +++ b/lib/ddnet-account-game-server/src/setup.rs @@ -1,92 +1,112 @@ +use ddnet_account_sql::any::AnyConnection; +use ddnet_account_sql::any::AnyPool; use ddnet_account_sql::version::get_version; -use ddnet_account_sql::version::set_version; -use sqlx::Acquire; -use sqlx::AnyConnection; -use sqlx::Connection; -use sqlx::Executor; -use sqlx::Statement; const VERSION_NAME: &str = "account-game-server"; -async fn setup_version1_generic( - con: &mut AnyConnection, - user_sql: &'static str, -) -> anyhow::Result<()> { - // first create all statements (syntax check) - let user = con.prepare(user_sql).await?; +#[cfg(feature = "mysql")] +mod mysql { + use ddnet_account_sql::any::AnyConnection; + use ddnet_account_sql::version::set_version; + use sqlx::Executor; + use sqlx::Statement; - // afterwards actually create tables - user.query().execute(&mut *con).await?; + use super::VERSION_NAME; - set_version(con, VERSION_NAME, 1).await?; + pub(super) async fn setup_version1( + con: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result<()> { + // first create all statements (syntax check) + let user = con.prepare(include_str!("setup/mysql/user.sql")).await?; - Ok(()) -} - -async fn delete_generic(pool: &sqlx::AnyPool, delete_sql: &'static str) -> anyhow::Result<()> { - let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; + // afterwards actually create tables + user.query().execute(&mut *con).await?; - // first create all statements (syntax check) - // delete in reverse order to creating - let user = con.prepare(delete_sql).await?; + set_version(&mut AnyConnection::MySql(con), VERSION_NAME, 1).await?; - // afterwards actually drop tables - let user = user.query().execute(&mut *con).await; + Ok(()) + } - let _ = set_version(con, VERSION_NAME, 0).await; + pub(super) async fn delete(con: &mut sqlx::mysql::MySqlConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + // delete in reverse order to creating + let user = con + .prepare(include_str!("setup/mysql/delete/user.sql")) + .await?; - // handle errors at once - user?; + // afterwards actually drop tables + let user = user.query().execute(&mut *con).await; - Ok(()) -} + let _ = set_version(&mut AnyConnection::MySql(con), VERSION_NAME, 0).await; -#[cfg(feature = "mysql")] -mod mysql { - use sqlx::AnyConnection; + // handle errors at once + user?; - pub(super) async fn setup_version1(con: &mut AnyConnection) -> anyhow::Result<()> { - super::setup_version1_generic(con, include_str!("setup/mysql/user.sql")).await - } - - pub(super) async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - super::delete_generic(pool, include_str!("setup/mysql/delete/user.sql")).await + Ok(()) } } #[cfg(feature = "sqlite")] mod sqlite { - use sqlx::AnyConnection; + use ddnet_account_sql::any::AnyConnection; + use ddnet_account_sql::version::set_version; + use sqlx::Executor; + use sqlx::Statement; + + use super::VERSION_NAME; + + pub(super) async fn setup_version1( + con: &mut sqlx::sqlite::SqliteConnection, + ) -> anyhow::Result<()> { + // first create all statements (syntax check) + let user = con.prepare(include_str!("setup/sqlite/user.sql")).await?; + + // afterwards actually create tables + user.query().execute(&mut *con).await?; + + set_version(&mut AnyConnection::Sqlite(con), VERSION_NAME, 1).await?; - pub(super) async fn setup_version1(con: &mut AnyConnection) -> anyhow::Result<()> { - super::setup_version1_generic(con, include_str!("setup/sqlite/user.sql")).await + Ok(()) } - pub(super) async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - super::delete_generic(pool, include_str!("setup/sqlite/delete/user.sql")).await + pub(super) async fn delete(con: &mut sqlx::sqlite::SqliteConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + // delete in reverse order to creating + let user = con + .prepare(include_str!("setup/sqlite/delete/user.sql")) + .await?; + + // afterwards actually drop tables + let user = user.query().execute(&mut *con).await; + + let _ = set_version(&mut AnyConnection::Sqlite(con), VERSION_NAME, 0).await; + + // handle errors at once + user?; + + Ok(()) } } -async fn setup_version1(con: &mut AnyConnection) -> anyhow::Result<()> { - match con.kind() { +async fn setup_version1(con: &mut AnyConnection<'_>) -> anyhow::Result<()> { + match con { #[cfg(feature = "mysql")] - sqlx::any::AnyKind::MySql => mysql::setup_version1(con).await, + AnyConnection::MySql(con) => mysql::setup_version1(con).await, #[cfg(feature = "sqlite")] - sqlx::any::AnyKind::Sqlite => sqlite::setup_version1(con).await, + AnyConnection::Sqlite(con) => sqlite::setup_version1(con).await, } } /// Sets up all tables required for a game server user -pub async fn setup(pool: &sqlx::AnyPool) -> anyhow::Result<()> { +pub async fn setup(pool: &AnyPool) -> anyhow::Result<()> { let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; + let mut con = pool_con.acquire().await?; - con.transaction(|con| { + con.transaction(|mut trans| { Box::pin(async move { - let version = get_version(con, VERSION_NAME).await?; + let version = get_version(&mut trans.con(), VERSION_NAME).await?; if version < 1 { - setup_version1(&mut *con).await?; + setup_version1(&mut trans.con()).await?; } anyhow::Ok(()) @@ -96,11 +116,13 @@ pub async fn setup(pool: &sqlx::AnyPool) -> anyhow::Result<()> { } /// Drop all tables related to a game server database setup -pub async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - match pool.any_kind() { +pub async fn delete(pool: &AnyPool) -> anyhow::Result<()> { + let mut con = pool.acquire().await?; + let con = con.acquire().await?; + match con { #[cfg(feature = "mysql")] - sqlx::any::AnyKind::MySql => mysql::delete(pool).await, + AnyConnection::MySql(con) => mysql::delete(con).await, #[cfg(feature = "sqlite")] - sqlx::any::AnyKind::Sqlite => sqlite::delete(pool).await, + AnyConnection::Sqlite(con) => sqlite::delete(con).await, } } diff --git a/lib/ddnet-account-game-server/src/tests/sqlite.rs b/lib/ddnet-account-game-server/src/tests/sqlite.rs index bae0d51..79e98b6 100644 --- a/lib/ddnet-account-game-server/src/tests/sqlite.rs +++ b/lib/ddnet-account-game-server/src/tests/sqlite.rs @@ -1,5 +1,6 @@ +use ddnet_account_sql::any::AnyPool; use ddnet_accounts_shared::game_server::user_id::UserId; -use sqlx::{any::AnyPoolOptions, sqlite::SqliteConnectOptions}; +use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; #[tokio::test] pub async fn sqlite() -> anyhow::Result<()> { @@ -7,15 +8,17 @@ pub async fn sqlite() -> anyhow::Result<()> { let _ = tokio::fs::remove_file(DB_FILE).await; const DB_FILE: &str = "test-db.sqlite"; - let pool = AnyPoolOptions::new() - .max_connections(10) - .connect_with( - SqliteConnectOptions::new() - .filename(DB_FILE) - .create_if_missing(true) - .into(), - ) - .await?; + sqlx::any::install_default_drivers(); + let pool = AnyPool::Sqlite( + SqlitePoolOptions::new() + .max_connections(10) + .connect_with( + SqliteConnectOptions::new() + .filename(DB_FILE) + .create_if_missing(true), + ) + .await?, + ); // setup crate::setup::setup(&pool).await?; diff --git a/lib/ddnet-account-sql/Cargo.toml b/lib/ddnet-account-sql/Cargo.toml index 206eb59..18dcf0e 100644 --- a/lib/ddnet-account-sql/Cargo.toml +++ b/lib/ddnet-account-sql/Cargo.toml @@ -8,10 +8,10 @@ description = "Helpers for SQL databases." repository = "https://github.com/ddnet/ddnet-accounts" [dependencies] -# https://github.com/launchbadge/sqlx/issues/2636 -sqlx = { version = "=0.6.3", features = ["any", "runtime-tokio-rustls", "chrono"] } +sqlx = { version = "0.8.2", features = ["any", "runtime-tokio-rustls", "chrono"] } async-trait = "0.1.83" anyhow = { version = "1.0.93", features = ["backtrace"] } +futures = "0.3.31" [features] mysql = ["sqlx/mysql"] diff --git a/lib/ddnet-account-sql/src/any.rs b/lib/ddnet-account-sql/src/any.rs new file mode 100644 index 0000000..91552a5 --- /dev/null +++ b/lib/ddnet-account-sql/src/any.rs @@ -0,0 +1,289 @@ +use futures::future::BoxFuture; +use sqlx::Acquire; + +#[derive(Debug)] +/// Enum variant over a database statement +pub enum AnyStatement<'a> { + #[cfg(feature = "mysql")] + /// Mysql statement + MySql(sqlx::mysql::MySqlStatement<'a>), + /// Sqlite statement + #[cfg(feature = "sqlite")] + Sqlite(sqlx::sqlite::SqliteStatement<'a>), +} + +/// Enum variant over a database row result +pub enum AnyRow { + #[cfg(feature = "mysql")] + /// Mysql query row result + MySql(sqlx::mysql::MySqlRow), + /// Sqlite query row result + #[cfg(feature = "sqlite")] + Sqlite(sqlx::sqlite::SqliteRow), +} + +#[derive(Debug)] +/// Enum variant over a database query result +pub enum AnyQueryResult { + #[cfg(feature = "mysql")] + /// Mysql query result + MySql(sqlx::mysql::MySqlQueryResult), + /// Sqlite query result + #[cfg(feature = "sqlite")] + Sqlite(sqlx::sqlite::SqliteQueryResult), +} + +impl AnyQueryResult { + /// How many rows were affected by the last query. + pub fn rows_affected(&self) -> u64 { + match self { + #[cfg(feature = "mysql")] + Self::MySql(res) => res.rows_affected(), + #[cfg(feature = "sqlite")] + Self::Sqlite(res) => res.rows_affected(), + } + } +} + +/// Enum variant over a database query +pub enum AnyQuery<'a> { + #[cfg(feature = "mysql")] + /// Mysql query + MySql(sqlx::query::Query<'a, sqlx::MySql, sqlx::mysql::MySqlArguments>), + /// Sqlite query + #[cfg(feature = "sqlite")] + Sqlite(sqlx::query::Query<'a, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'a>>), +} + +impl AnyQuery<'_> { + /// Executes the given query. + /// + /// See [sqlx::query::Query::execute]. + #[allow(irrefutable_let_patterns)] + pub async fn execute(self, con: &mut AnyConnection<'_>) -> Result { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(query) => { + let AnyConnection::MySql(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of mysql type, while query was.".into(), + )); + }; + AnyQueryResult::MySql(query.execute(&mut **con).await?) + } + #[cfg(feature = "sqlite")] + Self::Sqlite(query) => { + let AnyConnection::Sqlite(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of sqlite type, while query was.".into(), + )); + }; + AnyQueryResult::Sqlite(query.execute(&mut **con).await?) + } + }) + } + + /// Execute the query, returning the first row or [`sqlx::Error::RowNotFound`] otherwise. + /// + /// See [sqlx::query::Query::fetch_one]. + #[allow(irrefutable_let_patterns)] + pub async fn fetch_one(self, con: &mut AnyConnection<'_>) -> Result { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(query) => { + let AnyConnection::MySql(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of mysql type, while query was.".into(), + )); + }; + AnyRow::MySql(query.fetch_one(&mut **con).await?) + } + #[cfg(feature = "sqlite")] + Self::Sqlite(query) => { + let AnyConnection::Sqlite(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of sqlite type, while query was.".into(), + )); + }; + AnyRow::Sqlite(query.fetch_one(&mut **con).await?) + } + }) + } + + /// Execute the query and return all the resulting rows collected into a [`Vec`]. + /// + /// See [sqlx::query::Query::fetch_all]. + #[allow(irrefutable_let_patterns)] + pub async fn fetch_all(self, con: &mut AnyConnection<'_>) -> Result, sqlx::Error> { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(query) => { + let AnyConnection::MySql(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of mysql type, while query was.".into(), + )); + }; + query + .fetch_all(&mut **con) + .await? + .into_iter() + .map(AnyRow::MySql) + .collect() + } + #[cfg(feature = "sqlite")] + Self::Sqlite(query) => { + let AnyConnection::Sqlite(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of sqlite type, while query was.".into(), + )); + }; + query + .fetch_all(&mut **con) + .await? + .into_iter() + .map(AnyRow::Sqlite) + .collect() + } + }) + } + + /// Execute the query, returning the first row or `None` otherwise. + /// + /// See [sqlx::query::Query::fetch_optional]. + #[allow(irrefutable_let_patterns)] + pub async fn fetch_optional( + self, + con: &mut AnyConnection<'_>, + ) -> Result, sqlx::Error> { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(query) => { + let AnyConnection::MySql(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of mysql type, while query was.".into(), + )); + }; + query.fetch_optional(&mut **con).await?.map(AnyRow::MySql) + } + #[cfg(feature = "sqlite")] + Self::Sqlite(query) => { + let AnyConnection::Sqlite(con) = con else { + return Err(sqlx::Error::AnyDriverError( + "Connection was not of sqlite type, while query was.".into(), + )); + }; + query.fetch_optional(&mut **con).await?.map(AnyRow::Sqlite) + } + }) + } +} + +#[derive(Debug)] +/// Enum variant over a database transaction +pub enum AnyTransaction<'a, 'b> { + #[cfg(feature = "mysql")] + /// Mysql connection transaction + MySql(&'a mut sqlx::Transaction<'b, sqlx::MySql>), + /// Sqlite connection transaction + #[cfg(feature = "sqlite")] + Sqlite(&'a mut sqlx::Transaction<'b, sqlx::Sqlite>), +} + +impl AnyTransaction<'_, '_> { + /// Get the connection from this transaction + pub fn con(&mut self) -> AnyConnection<'_> { + match self { + #[cfg(feature = "mysql")] + AnyTransaction::MySql(trans) => AnyConnection::MySql(trans), + #[cfg(feature = "sqlite")] + AnyTransaction::Sqlite(trans) => AnyConnection::Sqlite(trans), + } + } +} + +#[derive(Debug)] +/// Enum variant over a database connection +pub enum AnyConnection<'a> { + #[cfg(feature = "mysql")] + /// Mysql connection + MySql(&'a mut sqlx::mysql::MySqlConnection), + /// Sqlite connection + #[cfg(feature = "sqlite")] + Sqlite(&'a mut sqlx::sqlite::SqliteConnection), +} + +impl AnyConnection<'_> { + /// Execute the function inside a transaction. + /// See [`sqlx::Connection::transaction`]. + pub async fn transaction<'a, F, R, E>(&'a mut self, callback: F) -> Result + where + for<'c> F: FnOnce(AnyTransaction<'c, '_>) -> BoxFuture<'c, Result> + 'a + Send + Sync, + Self: Sized, + R: Send, + E: From + Send, + { + use sqlx::Connection; + match self { + #[cfg(feature = "mysql")] + AnyConnection::MySql(con) => { + con.transaction(|transaction| callback(AnyTransaction::MySql(transaction))) + .await + } + #[cfg(feature = "sqlite")] + AnyConnection::Sqlite(con) => { + con.transaction(|transaction| callback(AnyTransaction::Sqlite(transaction))) + .await + } + } + } +} + +#[derive(Debug)] +/// Enum variant over a database pooled connection +pub enum AnyPoolConnection { + #[cfg(feature = "mysql")] + /// Mysql pool connection + MySql(sqlx::pool::PoolConnection), + /// Sqlite pool connection + #[cfg(feature = "sqlite")] + Sqlite(sqlx::pool::PoolConnection), +} + +impl AnyPoolConnection { + /// Retrieves the inner connection of this pool connection. + /// + /// See [sqlx::Acquire::acquire]. + pub async fn acquire(&mut self) -> Result { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(con) => AnyConnection::MySql(con.acquire().await?), + #[cfg(feature = "sqlite")] + Self::Sqlite(con) => AnyConnection::Sqlite(con.acquire().await?), + }) + } +} + +#[derive(Debug, Clone)] +/// Enum variant over a database connection pool +pub enum AnyPool { + #[cfg(feature = "mysql")] + /// Mysql pool + MySql(sqlx::mysql::MySqlPool), + /// Sqlite pool + #[cfg(feature = "sqlite")] + Sqlite(sqlx::sqlite::SqlitePool), +} + +impl AnyPool { + /// Retrieves a connection from the pool. + /// + /// See [sqlx::pool::Pool::acquire]. + pub async fn acquire(&self) -> Result { + Ok(match self { + #[cfg(feature = "mysql")] + Self::MySql(pool) => AnyPoolConnection::MySql(pool.acquire().await?), + #[cfg(feature = "sqlite")] + Self::Sqlite(pool) => AnyPoolConnection::Sqlite(pool.acquire().await?), + }) + } +} diff --git a/lib/ddnet-account-sql/src/lib.rs b/lib/ddnet-account-sql/src/lib.rs index 58e1b31..181cff4 100644 --- a/lib/ddnet-account-sql/src/lib.rs +++ b/lib/ddnet-account-sql/src/lib.rs @@ -6,11 +6,13 @@ #![deny(clippy::nursery)] #![deny(clippy::all)] +use any::AnyQueryResult; + #[cfg(not(any(feature = "mysql", feature = "sqlite")))] std::compile_error!("at least the mysql or sqlite feature must be used."); -use sqlx::{any::AnyQueryResult, Error}; - +/// Our version of sqlx any variants +pub mod any; /// Everything related to queries pub mod query; /// Everything related to versioning table setups @@ -18,14 +20,10 @@ pub mod version; /// Checks if the query result resulted in an error that indicates /// a duplicate entry. -pub fn is_duplicate_entry(res: &Result) -> bool { +pub fn is_duplicate_entry(res: &Result) -> bool { res.as_ref().is_err_and(|err| { if let sqlx::Error::Database(err) = err { - [23000, 23001].contains( - &err.code() - .and_then(|code| code.parse::().ok()) - .unwrap_or_default(), - ) + matches!(err.kind(), sqlx::error::ErrorKind::UniqueViolation) } else { false } diff --git a/lib/ddnet-account-sql/src/query.rs b/lib/ddnet-account-sql/src/query.rs index b0ade2a..6afa2dc 100644 --- a/lib/ddnet-account-sql/src/query.rs +++ b/lib/ddnet-account-sql/src/query.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; -use sqlx::any::{AnyKind, AnyRow}; + +use crate::any::{AnyConnection, AnyQuery, AnyRow, AnyStatement}; /// An interface for queries to allow converting them to various database implementations #[async_trait] @@ -7,56 +8,68 @@ pub trait Query { /// MySQL version of [`Query::prepare`]. #[cfg(feature = "mysql")] async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result>; + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result>; /// Sqlite version of [`Query::prepare`]. #[cfg(feature = "sqlite")] async fn prepare_sqlite( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result>; + connection: &mut sqlx::sqlite::SqliteConnection, + ) -> anyhow::Result>; /// Prepare a statement to be later used by [`Query::query`]. - async fn prepare( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { - match connection.kind() { + async fn prepare(connection: &mut AnyConnection) -> anyhow::Result> { + Ok(match connection { #[cfg(feature = "mysql")] - AnyKind::MySql => Self::prepare_mysql(connection).await, + AnyConnection::MySql(connection) => { + AnyStatement::MySql(Self::prepare_mysql(connection).await?) + } #[cfg(feature = "sqlite")] - AnyKind::Sqlite => Self::prepare_sqlite(connection).await, - //_ => Err(anyhow!("database backend not implemented.")), - } + AnyConnection::Sqlite(connection) => { + AnyStatement::Sqlite(Self::prepare_sqlite(connection).await?) + } + }) } /// MySQL version of [`Query::query`]. #[cfg(feature = "mysql")] fn query_mysql<'a>( &'a self, - statement: &'a sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'a, sqlx::Any, sqlx::any::AnyArguments<'a>>; + statement: &'a sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'a, sqlx::MySql, sqlx::mysql::MySqlArguments>; /// Sqlite version of [`Query::query`]. #[cfg(feature = "sqlite")] fn query_sqlite<'a>( &'a self, - statement: &'a sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'a, sqlx::Any, sqlx::any::AnyArguments<'a>>; + statement: &'a sqlx::sqlite::SqliteStatement<'static>, + ) -> sqlx::query::Query<'a, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'a>>; /// Get a query with all arguments bound already, ready to be fetched. - fn query<'a>( - &'a self, - connection: &sqlx::AnyConnection, - statement: &'a sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'a, sqlx::Any, sqlx::any::AnyArguments<'a>> { - match connection.kind() { + fn query<'a>(&'a self, statement: &'a AnyStatement<'static>) -> AnyQuery<'a> { + match statement { #[cfg(feature = "mysql")] - AnyKind::MySql => self.query_mysql(statement), + AnyStatement::MySql(statement) => AnyQuery::MySql(self.query_mysql(statement)), #[cfg(feature = "sqlite")] - AnyKind::Sqlite => self.query_sqlite(statement), + AnyStatement::Sqlite(statement) => AnyQuery::Sqlite(self.query_sqlite(statement)), } } + /// MySQL version of [`Query::row_data`]. + #[cfg(feature = "mysql")] + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result; + + /// Sqlite version of [`Query::row_data`]. + #[cfg(feature = "sqlite")] + fn row_data_sqlite(row: &sqlx::sqlite::SqliteRow) -> anyhow::Result; + /// Gets the row data for a result row of this query - fn row_data(row: &AnyRow) -> anyhow::Result; + fn row_data(row: &AnyRow) -> anyhow::Result { + match row { + #[cfg(feature = "mysql")] + AnyRow::MySql(row) => Self::row_data_mysql(row), + #[cfg(feature = "sqlite")] + AnyRow::Sqlite(row) => Self::row_data_sqlite(row), + } + } } diff --git a/lib/ddnet-account-sql/src/version.rs b/lib/ddnet-account-sql/src/version.rs index 6fdb65b..e12e494 100644 --- a/lib/ddnet-account-sql/src/version.rs +++ b/lib/ddnet-account-sql/src/version.rs @@ -1,164 +1,182 @@ -use sqlx::Acquire; -use sqlx::AnyConnection; -use sqlx::Executor; -use sqlx::Row; -use sqlx::Statement; - -async fn try_setup_generic(con: &mut AnyConnection, sql: &'static str) -> anyhow::Result<()> { - // first create all statements (syntax check) - let version = con.prepare(sql).await?; - - // afterwards actually create tables - version.query().execute(&mut *con).await?; - - Ok(()) -} - -async fn get_or_set_version_generic( - con: &mut AnyConnection, - name: &str, - get_version_sql: &'static str, - set_version_sql: &'static str, -) -> anyhow::Result { - // first create all statements (syntax check) - let get_version = con.prepare(get_version_sql).await?; - let set_version = con.prepare(set_version_sql).await?; - - let name = name.to_string(); - - // afterwards actually create tables - if let Some(row) = get_version - .query() - .bind(&name) - .fetch_optional(&mut *con) - .await? - { - anyhow::Ok(row.try_get("version")?) - } else { - // insert new entry - set_version - .query() - .bind(&name) - .bind(0) - .bind(0) - .execute(&mut *con) - .await?; - anyhow::Ok(0) - } -} - -async fn set_version_generic( - con: &mut AnyConnection, - name: &str, - version: i64, - set_version_sql: &'static str, -) -> anyhow::Result<()> { - // first create all statements (syntax check) - let set_version = con.prepare(set_version_sql).await?; - - Ok(set_version - .query() - .bind(name) - .bind(version) - .bind(version) - .execute(&mut *con) - .await - .map(|_| ())?) -} - -async fn delete_genric(pool: &sqlx::AnyPool, delete_sql: &'static str) -> anyhow::Result<()> { - let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; - - // first create all statements (syntax check) - // delete in reverse order to creating - let version = con.prepare(delete_sql).await?; - - // afterwards actually drop tables - let version = version.query().execute(&mut *con).await; - - // handle errors at once - version?; - - Ok(()) -} +use crate::any::{AnyConnection, AnyPool}; #[cfg(feature = "mysql")] mod mysql { - use sqlx::AnyConnection; + use sqlx::Executor; + use sqlx::Row; + use sqlx::Statement; + + pub(super) async fn try_setup(con: &mut sqlx::mysql::MySqlConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + let version = con + .prepare(include_str!("version/mysql/version.sql")) + .await?; - pub(super) async fn try_setup(con: &mut AnyConnection) -> anyhow::Result<()> { - super::try_setup_generic(con, include_str!("version/mysql/version.sql")).await + // afterwards actually create tables + version.query().execute(&mut *con).await?; + + Ok(()) } pub(super) async fn get_or_set_version( - con: &mut AnyConnection, + con: &mut sqlx::mysql::MySqlConnection, name: &str, ) -> anyhow::Result { - super::get_or_set_version_generic( - con, - name, - include_str!("version/mysql/get_version.sql"), - include_str!("version/mysql/set_version.sql"), - ) - .await + // first create all statements (syntax check) + let get_version = con + .prepare(include_str!("version/mysql/get_version.sql")) + .await?; + let set_version = con + .prepare(include_str!("version/mysql/set_version.sql")) + .await?; + + let name = name.to_string(); + + // afterwards actually create tables + if let Some(row) = get_version + .query() + .bind(&name) + .fetch_optional(&mut *con) + .await? + { + anyhow::Ok(row.try_get("version")?) + } else { + // insert new entry + set_version + .query() + .bind(&name) + .bind(0) + .bind(0) + .execute(&mut *con) + .await?; + anyhow::Ok(0) + } } pub(super) async fn set_version( - con: &mut AnyConnection, + con: &mut sqlx::mysql::MySqlConnection, name: &str, version: i64, ) -> anyhow::Result<()> { - super::set_version_generic( - con, - name, - version, - include_str!("version/mysql/set_version.sql"), - ) - .await + // first create all statements (syntax check) + let set_version = con + .prepare(include_str!("version/mysql/set_version.sql")) + .await?; + + Ok(set_version + .query() + .bind(name) + .bind(version) + .bind(version) + .execute(&mut *con) + .await + .map(|_| ())?) } - pub(super) async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - super::delete_genric(pool, include_str!("version/mysql/delete/version.sql")).await + pub(super) async fn delete(con: &mut sqlx::mysql::MySqlConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + // delete in reverse order to creating + let version = con + .prepare(include_str!("version/mysql/delete/version.sql")) + .await?; + + // afterwards actually drop tables + let version = version.query().execute(&mut *con).await; + + // handle errors at once + version?; + + Ok(()) } } #[cfg(feature = "sqlite")] mod sqlite { - use sqlx::AnyConnection; - pub(super) async fn try_setup(con: &mut AnyConnection) -> anyhow::Result<()> { - super::try_setup_generic(con, include_str!("version/sqlite/version.sql")).await + use sqlx::Executor; + use sqlx::Row; + use sqlx::Statement; + + pub(super) async fn try_setup(con: &mut sqlx::sqlite::SqliteConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + let version = con + .prepare(include_str!("version/sqlite/version.sql")) + .await?; + + // afterwards actually create tables + version.query().execute(&mut *con).await?; + + Ok(()) } pub(super) async fn get_or_set_version( - con: &mut AnyConnection, + con: &mut sqlx::sqlite::SqliteConnection, name: &str, ) -> anyhow::Result { - super::get_or_set_version_generic( - con, - name, - include_str!("version/sqlite/get_version.sql"), - include_str!("version/sqlite/set_version.sql"), - ) - .await + // first create all statements (syntax check) + let get_version = con + .prepare(include_str!("version/sqlite/get_version.sql")) + .await?; + let set_version = con + .prepare(include_str!("version/sqlite/set_version.sql")) + .await?; + + let name = name.to_string(); + + // afterwards actually create tables + if let Some(row) = get_version + .query() + .bind(&name) + .fetch_optional(&mut *con) + .await? + { + anyhow::Ok(row.try_get("version")?) + } else { + // insert new entry + set_version + .query() + .bind(&name) + .bind(0) + .bind(0) + .execute(&mut *con) + .await?; + anyhow::Ok(0) + } } - pub(super) async fn set_versione( - con: &mut AnyConnection, + pub(super) async fn set_version( + con: &mut sqlx::sqlite::SqliteConnection, name: &str, version: i64, ) -> anyhow::Result<()> { - super::set_version_generic( - con, - name, - version, - include_str!("version/sqlite/set_version.sql"), - ) - .await + // first create all statements (syntax check) + let set_version = con + .prepare(include_str!("version/sqlite/set_version.sql")) + .await?; + + Ok(set_version + .query() + .bind(name) + .bind(version) + .bind(version) + .execute(&mut *con) + .await + .map(|_| ())?) } - pub(super) async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - super::delete_genric(pool, include_str!("version/sqlite/delete/version.sql")).await + pub(super) async fn delete(con: &mut sqlx::sqlite::SqliteConnection) -> anyhow::Result<()> { + // first create all statements (syntax check) + // delete in reverse order to creating + let version = con + .prepare(include_str!("version/sqlite/delete/version.sql")) + .await?; + + // afterwards actually drop tables + let version = version.query().execute(&mut *con).await; + + // handle errors at once + version?; + + Ok(()) } } @@ -167,16 +185,16 @@ mod sqlite { /// If the version table does not exist, sets up the version table. /// The version table can be used to easily upgrade existing tables to a new /// version, without manually doing it by hand. -pub async fn get_version(con: &mut AnyConnection, name: &str) -> anyhow::Result { - match con.kind() { +pub async fn get_version(con: &mut AnyConnection<'_>, name: &str) -> anyhow::Result { + match con { #[cfg(feature = "mysql")] - sqlx::any::AnyKind::MySql => { + AnyConnection::MySql(con) => { // try setup mysql::try_setup(con).await?; mysql::get_or_set_version(con, name).await } #[cfg(feature = "sqlite")] - sqlx::any::AnyKind::Sqlite => { + AnyConnection::Sqlite(con) => { // try setup sqlite::try_setup(con).await?; sqlite::get_or_set_version(con, name).await @@ -186,22 +204,28 @@ pub async fn get_version(con: &mut AnyConnection, name: &str) -> anyhow::Result< /// After your setup is done, set the version to your current setup script. /// This can (and should) be called inside a transaction -pub async fn set_version(con: &mut AnyConnection, name: &str, version: i64) -> anyhow::Result<()> { - match con.kind() { +pub async fn set_version( + con: &mut AnyConnection<'_>, + name: &str, + version: i64, +) -> anyhow::Result<()> { + match con { #[cfg(feature = "mysql")] - sqlx::any::AnyKind::MySql => mysql::set_version(con, name, version).await, + AnyConnection::MySql(con) => mysql::set_version(con, name, version).await, #[cfg(feature = "sqlite")] - sqlx::any::AnyKind::Sqlite => sqlite::set_versione(con, name, version).await, + AnyConnection::Sqlite(con) => sqlite::set_version(con, name, version).await, } } /// Drop the version table... /// Warning: This is usually not recommended. -pub async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - match pool.any_kind() { +pub async fn delete(pool: &AnyPool) -> anyhow::Result<()> { + let mut con = pool.acquire().await?; + let con = con.acquire().await?; + match con { #[cfg(feature = "mysql")] - sqlx::any::AnyKind::MySql => mysql::delete(pool).await, + AnyConnection::MySql(con) => mysql::delete(con).await, #[cfg(feature = "sqlite")] - sqlx::any::AnyKind::Sqlite => sqlite::delete(pool).await, + AnyConnection::Sqlite(con) => sqlite::delete(con).await, } } diff --git a/lib/ddnet-accounts-shared/Cargo.toml b/lib/ddnet-accounts-shared/Cargo.toml index 9100b92..ed115b7 100644 --- a/lib/ddnet-accounts-shared/Cargo.toml +++ b/lib/ddnet-accounts-shared/Cargo.toml @@ -26,7 +26,7 @@ const-oid = "0.9.6" der = { version = "0.7.9", features = ["derive"] } ecdsa = { version = "0.16.9", features = ["digest", "pem"] } p256 = "0.13.2" -thiserror = "1.0.69" +thiserror = "2.0.3" url = { version = "2.5.4", features = ["serde"] } strum = { version = "0.26.3", features = ["derive"] } diff --git a/src/account_info.rs b/src/account_info.rs index 8fa6215..42fb1f3 100644 --- a/src/account_info.rs +++ b/src/account_info.rs @@ -3,7 +3,7 @@ pub mod queries; use std::{str::FromStr, sync::Arc}; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ account_info::{AccountInfoResponse, CredentialType}, @@ -13,7 +13,6 @@ use ddnet_accounts_shared::{ client::account_info::AccountInfoRequest, }; use queries::AccountInfo; -use sqlx::{Acquire, AnyPool}; use crate::shared::{Shared, CERT_MAX_AGE_DELTA, CERT_MIN_AGE_DELTA}; @@ -47,7 +46,7 @@ pub async fn account_info( ); let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; // fetch account info let qry = AccountInfo { @@ -56,8 +55,8 @@ pub async fn account_info( }; let row = qry - .query(connection, &shared.db.account_info) - .fetch_one(connection) + .query(&shared.db.account_info) + .fetch_one(&mut connection) .await?; let account_info = AccountInfo::row_data(&row)?; diff --git a/src/account_info/queries.rs b/src/account_info/queries.rs index 0738133..9d7a98f 100644 --- a/src/account_info/queries.rs +++ b/src/account_info/queries.rs @@ -3,7 +3,6 @@ use axum::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::machine_id::MachineUid; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Row; use sqlx::Statement; @@ -23,22 +22,22 @@ pub struct AccountInfoData { #[async_trait] impl Query for AccountInfo<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/account_info.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement .query() .bind(self.session_pub_key.as_slice()) .bind(self.session_hw_id.as_slice()) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AccountInfoData { account_id: row .try_get("account_id") diff --git a/src/account_token.rs b/src/account_token.rs index 98e949e..059fbef 100644 --- a/src/account_token.rs +++ b/src/account_token.rs @@ -3,7 +3,7 @@ pub mod queries; use std::sync::Arc; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ account_token::AccountTokenError, errors::AccountServerRequestError, otp::generate_otp, @@ -14,7 +14,6 @@ use ddnet_accounts_shared::{ }, }; use queries::{AddAccountTokenEmail, AddAccountTokenSteam}; -use sqlx::{Acquire, AnyPool}; use crate::shared::Shared; @@ -75,11 +74,11 @@ pub async fn account_token_email_impl( ty: &data.op, }; let mut connection = pool.acquire().await?; - let con = connection.acquire().await?; + let mut con = connection.acquire().await?; let account_token_res = query_add_account_token - .query(con, &shared.db.account_token_email_statement) - .execute(&mut *con) + .query(&shared.db.account_token_email_statement) + .execute(&mut con) .await?; anyhow::ensure!( account_token_res.rows_affected() >= 1, @@ -148,11 +147,11 @@ pub async fn account_token_steam_impl( ty: &data.op, }; let mut connection = pool.acquire().await?; - let con = connection.acquire().await?; + let mut con = connection.acquire().await?; let account_token_res = query_add_account_token - .query(con, &shared.db.account_token_steam_statement) - .execute(&mut *con) + .query(&shared.db.account_token_steam_statement) + .execute(&mut con) .await?; anyhow::ensure!( account_token_res.rows_affected() >= 1, diff --git a/src/account_token/queries.rs b/src/account_token/queries.rs index 05b4eb1..4840ace 100644 --- a/src/account_token/queries.rs +++ b/src/account_token/queries.rs @@ -5,7 +5,6 @@ use async_trait::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::account_token::AccountToken; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Row; use sqlx::Statement; @@ -22,16 +21,16 @@ pub struct AddAccountTokenEmail<'a> { #[async_trait] impl Query<()> for AddAccountTokenEmail<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_account_token_email.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let ty: &'static str = self.ty.into(); statement .query() @@ -39,7 +38,7 @@ impl Query<()> for AddAccountTokenEmail<'_> { .bind(self.email.as_str()) .bind(ty) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -54,16 +53,16 @@ pub struct AddAccountTokenSteam<'a> { #[async_trait] impl Query<()> for AddAccountTokenSteam<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_account_token_steam.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let ty: &'static str = self.ty.into(); statement .query() @@ -71,7 +70,7 @@ impl Query<()> for AddAccountTokenSteam<'_> { .bind(self.steamid64) .bind(ty) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -88,19 +87,19 @@ pub struct AccountTokenData { #[async_trait] impl Query for AccountTokenQry<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/account_token_data.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.token.as_slice()) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AccountTokenData { account_id: row .try_get("account_id") @@ -120,19 +119,19 @@ pub struct InvalidateAccountToken<'a> { #[async_trait] impl Query<()> for InvalidateAccountToken<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/invalidate_account_token.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.token.as_slice()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/certs.rs b/src/certs.rs index 76cf91d..166f355 100644 --- a/src/certs.rs +++ b/src/certs.rs @@ -4,7 +4,7 @@ use std::{str::FromStr, sync::Arc, time::Duration}; use anyhow::anyhow; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::account_server::{ errors::{AccountServerRequestError, Empty}, result::AccountServerReqResult, @@ -13,7 +13,6 @@ use der::{Decode, Encode}; use p256::ecdsa::{DerSignature, SigningKey}; use queries::{AddCert, GetCerts}; use serde::{Deserialize, Serialize}; -use sqlx::{Acquire, AnyPool, Executor}; use x509_cert::{ builder::{Builder, Profile}, name::Name, @@ -145,10 +144,11 @@ pub async fn store_cert( }; let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; - let res = connection - .execute(qry.query(connection, &db.add_cert_statement)) + let res = qry + .query(&db.add_cert_statement) + .execute(&mut connection) .await?; anyhow::ensure!(res.rows_affected() >= 1); @@ -162,10 +162,11 @@ pub async fn get_certs( let qry = GetCerts {}; let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; - let cert_rows = connection - .fetch_all(qry.query(connection, &db.get_certs_statement)) + let cert_rows = qry + .query(&db.get_certs_statement) + .fetch_all(&mut connection) .await?; cert_rows diff --git a/src/certs/queries.rs b/src/certs/queries.rs index 2853a70..e7104b8 100644 --- a/src/certs/queries.rs +++ b/src/certs/queries.rs @@ -1,7 +1,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Row; use sqlx::Statement; @@ -14,19 +13,19 @@ pub struct AddCert<'a> { #[async_trait] impl Query<()> for AddCert<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_cert.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.cert_der).bind(self.valid_until) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -40,19 +39,19 @@ pub struct SingleCertData { #[async_trait] impl Query for GetCerts { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/get_certs.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(SingleCertData { cert_der: row .try_get("cert_der") diff --git a/src/credential_auth_token.rs b/src/credential_auth_token.rs index bfdd315..3fffc35 100644 --- a/src/credential_auth_token.rs +++ b/src/credential_auth_token.rs @@ -3,7 +3,7 @@ pub mod queries; use std::sync::Arc; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ credential_auth_token::CredentialAuthTokenError, errors::AccountServerRequestError, @@ -14,7 +14,6 @@ use ddnet_accounts_shared::{ CredentialAuthTokenSteamRequest, }, }; -use sqlx::{Acquire, AnyPool}; use crate::{ credential_auth_token::queries::AddCredentialAuthToken, shared::Shared, types::TokenType, @@ -96,11 +95,11 @@ pub async fn credential_auth_token_email_impl( op: &data.op, }; let mut connection = pool.acquire().await?; - let con = connection.acquire().await?; + let mut con = connection.acquire().await?; let credential_auth_token_res = query_add_credential_auth_token - .query(con, &shared.db.credential_auth_token_statement) - .execute(&mut *con) + .query(&shared.db.credential_auth_token_statement) + .execute(&mut con) .await?; anyhow::ensure!( credential_auth_token_res.rows_affected() >= 1, @@ -173,11 +172,11 @@ pub async fn credential_auth_token_steam_impl( op: &data.op, }; let mut connection = pool.acquire().await?; - let con = connection.acquire().await?; + let mut con = connection.acquire().await?; let credential_auth_token_res = query_add_credential_auth_token - .query(con, &shared.db.credential_auth_token_statement) - .execute(&mut *con) + .query(&shared.db.credential_auth_token_statement) + .execute(&mut con) .await?; anyhow::ensure!( credential_auth_token_res.rows_affected() >= 1, diff --git a/src/credential_auth_token/queries.rs b/src/credential_auth_token/queries.rs index a2280e5..1a82dd0 100644 --- a/src/credential_auth_token/queries.rs +++ b/src/credential_auth_token/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::credential_auth_token::CredentialAuthTokenOperation; use ddnet_accounts_shared::client::login::CredentialAuthToken; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -19,16 +18,16 @@ pub struct AddCredentialAuthToken<'a> { #[async_trait::async_trait] impl Query<()> for AddCredentialAuthToken<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_credential_auth_token.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let ty: &'static str = self.ty.into(); let op: &'static str = self.op.into(); statement @@ -38,7 +37,7 @@ impl Query<()> for AddCredentialAuthToken<'_> { .bind(self.identifier) .bind(op) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/db.rs b/src/db.rs index acbe6bd..d680ac6 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,4 +1,4 @@ -use sqlx::any::AnyStatement; +use ddnet_account_sql::any::AnyStatement; /// Shared data for a db connection pub struct DbConnectionShared { diff --git a/src/delete.rs b/src/delete.rs index 3d5416a..a026e2d 100644 --- a/src/delete.rs +++ b/src/delete.rs @@ -3,7 +3,7 @@ pub mod queries; use std::sync::Arc; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ errors::{AccountServerRequestError, Empty}, @@ -11,7 +11,6 @@ use ddnet_accounts_shared::{ }, client::delete::DeleteRequest, }; -use sqlx::{Acquire, AnyPool, Connection}; use crate::{ account_token::queries::{AccountTokenQry, InvalidateAccountToken}, @@ -41,10 +40,10 @@ pub async fn delete_request( pub async fn delete(shared: Arc, pool: AnyPool, data: DeleteRequest) -> anyhow::Result<()> { let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; connection - .transaction(|connection| { + .transaction(|mut connection| { Box::pin(async move { // token data let acc_token_qry = AccountTokenQry { @@ -52,8 +51,8 @@ pub async fn delete(shared: Arc, pool: AnyPool, data: DeleteRequest) -> }; let row = acc_token_qry - .query(connection, &shared.db.account_token_qry_statement) - .fetch_one(&mut **connection) + .query(&shared.db.account_token_qry_statement) + .fetch_one(&mut connection.con()) .await?; let token_data = AccountTokenQry::row_data(&row)?; @@ -62,8 +61,8 @@ pub async fn delete(shared: Arc, pool: AnyPool, data: DeleteRequest) -> let qry = InvalidateAccountToken { token: &data.account_token, }; - qry.query(connection, &shared.db.invalidate_account_token_statement) - .execute(&mut **connection) + qry.query(&shared.db.invalidate_account_token_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!( @@ -78,23 +77,23 @@ pub async fn delete(shared: Arc, pool: AnyPool, data: DeleteRequest) -> session_data: &None, }; - qry.query(connection, &shared.db.remove_sessions_except_statement) - .execute(&mut **connection) + qry.query(&shared.db.remove_sessions_except_statement) + .execute(&mut connection.con()) .await?; // Unlink all credentials let qry = UnlinkCredentialEmail { account_id: &account_id, }; - qry.query(connection, &shared.db.unlink_credential_email_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_email_statement) + .execute(&mut connection.con()) .await?; let qry = UnlinkCredentialSteam { account_id: &account_id, }; - qry.query(connection, &shared.db.unlink_credential_steam_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_steam_statement) + .execute(&mut connection.con()) .await?; // delete account @@ -102,8 +101,8 @@ pub async fn delete(shared: Arc, pool: AnyPool, data: DeleteRequest) -> account_id: &account_id, }; - qry.query(connection, &shared.db.remove_account_statement) - .execute(&mut **connection) + qry.query(&shared.db.remove_account_statement) + .execute(&mut connection.con()) .await?; anyhow::Ok(()) diff --git a/src/delete/queries.rs b/src/delete/queries.rs index f36d631..f99ecb8 100644 --- a/src/delete/queries.rs +++ b/src/delete/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -13,19 +12,19 @@ pub struct RemoveAccount<'a> { #[async_trait] impl Query<()> for RemoveAccount<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/rem_account.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.account_id) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/link_credential.rs b/src/link_credential.rs index 5e67e8c..e747e23 100644 --- a/src/link_credential.rs +++ b/src/link_credential.rs @@ -3,7 +3,7 @@ pub mod queries; use std::{str::FromStr, sync::Arc}; use axum::Json; -use ddnet_account_sql::{is_duplicate_entry, query::Query}; +use ddnet_account_sql::{any::AnyPool, is_duplicate_entry, query::Query}; use ddnet_accounts_shared::{ account_server::{ errors::{AccountServerRequestError, Empty}, @@ -14,7 +14,6 @@ use ddnet_accounts_shared::{ }, }; use queries::{UnlinkCredentialEmail, UnlinkCredentialSteam}; -use sqlx::{Acquire, AnyPool, Connection}; use crate::{ account_token::queries::{AccountTokenQry, InvalidateAccountToken}, @@ -46,10 +45,10 @@ pub async fn link_credential( data: LinkCredentialRequest, ) -> anyhow::Result<()> { let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; connection - .transaction(|connection| { + .transaction(|mut connection| { Box::pin(async move { // token data let acc_token_qry = AccountTokenQry { @@ -57,8 +56,8 @@ pub async fn link_credential( }; let row = acc_token_qry - .query(connection, &shared.db.account_token_qry_statement) - .fetch_one(&mut **connection) + .query(&shared.db.account_token_qry_statement) + .fetch_one(&mut connection.con()) .await?; let token_data = AccountTokenQry::row_data(&row)?; @@ -67,8 +66,8 @@ pub async fn link_credential( let qry = InvalidateAccountToken { token: &data.account_token, }; - qry.query(connection, &shared.db.invalidate_account_token_statement) - .execute(&mut **connection) + qry.query(&shared.db.invalidate_account_token_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!( @@ -80,7 +79,7 @@ pub async fn link_credential( let token_data = get_and_invalidate_credential_auth_token( &shared, data.credential_auth_token, - connection, + &mut connection.con(), ) .await? .ok_or_else(|| anyhow::anyhow!("Credential auth token is invalid/expired."))?; @@ -97,8 +96,8 @@ pub async fn link_credential( account_id: &account_id, }; - qry.query(connection, &shared.db.unlink_credential_email_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_email_statement) + .execute(&mut connection.con()) .await?; // add the new email. @@ -108,8 +107,8 @@ pub async fn link_credential( }; let res = qry - .query(connection, &shared.db.link_credentials_email_qry_statement) - .execute(&mut **connection) + .query(&shared.db.link_credentials_email_qry_statement) + .execute(&mut connection.con()) .await; anyhow::ensure!( @@ -125,8 +124,8 @@ pub async fn link_credential( account_id: &account_id, }; - qry.query(connection, &shared.db.unlink_credential_steam_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_steam_statement) + .execute(&mut connection.con()) .await?; // add the new steam. @@ -136,8 +135,8 @@ pub async fn link_credential( }; let res = qry - .query(connection, &shared.db.link_credentials_steam_qry_statement) - .execute(&mut **connection) + .query(&shared.db.link_credentials_steam_qry_statement) + .execute(&mut connection.con()) .await; anyhow::ensure!( diff --git a/src/link_credential/queries.rs b/src/link_credential/queries.rs index 3832ae6..adde60e 100644 --- a/src/link_credential/queries.rs +++ b/src/link_credential/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -13,19 +12,19 @@ pub struct UnlinkCredentialEmail<'a> { #[async_trait] impl Query<()> for UnlinkCredentialEmail<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/unlink_credential_email.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.account_id) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -37,19 +36,19 @@ pub struct UnlinkCredentialSteam<'a> { #[async_trait] impl Query<()> for UnlinkCredentialSteam<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/unlink_credential_steam.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.account_id) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/login.rs b/src/login.rs index 2eae471..617a961 100644 --- a/src/login.rs +++ b/src/login.rs @@ -3,7 +3,10 @@ pub mod queries; use std::{str::FromStr, sync::Arc}; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{ + any::{AnyConnection, AnyPool}, + query::Query, +}; use ddnet_accounts_shared::{ account_server::{ errors::AccountServerRequestError, login::LoginError, result::AccountServerReqResult, @@ -15,7 +18,6 @@ use queries::{ AccountIdFromEmail, AccountIdFromLastInsert, AccountIdFromSteam, CredentialAuthTokenData, LinkAccountCredentialEmail, LinkAccountCredentialSteam, }; -use sqlx::{Acquire, AnyConnection, AnyPool, Connection}; use crate::{ shared::Shared, @@ -45,7 +47,7 @@ enum LoginResponse { pub async fn get_and_invalidate_credential_auth_token( shared: &Arc, credential_auth_token: CredentialAuthToken, - connection: &mut AnyConnection, + connection: &mut AnyConnection<'_>, ) -> anyhow::Result> { // token data let credential_auth_token_qry = CredentialAuthTokenQry { @@ -53,7 +55,7 @@ pub async fn get_and_invalidate_credential_auth_token( }; let row = credential_auth_token_qry - .query(connection, &shared.db.credential_auth_token_qry_statement) + .query(&shared.db.credential_auth_token_qry_statement) .fetch_optional(connection) .await?; @@ -78,15 +80,15 @@ pub async fn login( )?; let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; let res = connection - .transaction(|connection| { + .transaction(|mut connection| { Box::pin(async move { let token_data = get_and_invalidate_credential_auth_token( &shared, data.credential_auth_token, - connection, + &mut connection.con(), ) .await?; @@ -114,12 +116,9 @@ pub async fn login( let qry = InvalidateCredentialAuthToken { token: &data.credential_auth_token, }; - qry.query( - connection, - &shared.db.invalidate_credential_auth_token_statement, - ) - .execute(&mut **connection) - .await?; + qry.query(&shared.db.invalidate_credential_auth_token_statement) + .execute(&mut connection.con()) + .await?; // create account (if not exists) let account_id = match &identifier { @@ -128,8 +127,8 @@ pub async fn login( let qry = AccountIdFromEmail { email }; let row = qry - .query(connection, &shared.db.account_id_from_email_qry_statement) - .fetch_optional(&mut **connection) + .query(&shared.db.account_id_from_email_qry_statement) + .fetch_optional(&mut connection.con()) .await?; row.map(|row| AccountIdFromEmail::row_data(&row)) @@ -141,8 +140,8 @@ pub async fn login( let qry = AccountIdFromSteam { steamid64 }; let row = qry - .query(connection, &shared.db.account_id_from_steam_qry_statement) - .fetch_optional(&mut **connection) + .query(&shared.db.account_id_from_steam_qry_statement) + .fetch_optional(&mut connection.con()) .await?; row.map(|row| AccountIdFromSteam::row_data(&row)) @@ -157,8 +156,8 @@ pub async fn login( let qry = TryCreateAccount {}; let res = qry - .query(connection, &shared.db.try_create_account_statement) - .execute(&mut **connection) + .query(&shared.db.try_create_account_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!(res.rows_affected() >= 1, "account was not created"); @@ -166,11 +165,8 @@ pub async fn login( // query account data let login_qry = AccountIdFromLastInsert {}; let row = login_qry - .query( - connection, - &shared.db.account_id_from_last_insert_qry_statement, - ) - .fetch_one(&mut **connection) + .query(&shared.db.account_id_from_last_insert_qry_statement) + .fetch_one(&mut connection.con()) .await?; let login_data = AccountIdFromLastInsert::row_data(&row)?; @@ -183,11 +179,8 @@ pub async fn login( }; let res = qry - .query( - connection, - &shared.db.link_credentials_email_qry_statement, - ) - .execute(&mut **connection) + .query(&shared.db.link_credentials_email_qry_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!( @@ -202,11 +195,8 @@ pub async fn login( }; let res = qry - .query( - connection, - &shared.db.link_credentials_steam_qry_statement, - ) - .execute(&mut **connection) + .query(&shared.db.link_credentials_steam_qry_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!( @@ -225,8 +215,8 @@ pub async fn login( pub_key: data.account_data.public_key.as_bytes(), }; - qry.query(connection, &shared.db.create_session_statement) - .execute(&mut **connection) + qry.query(&shared.db.create_session_statement) + .execute(&mut connection.con()) .await?; anyhow::Ok(LoginResponse::Success(account_id)) diff --git a/src/login/queries.rs b/src/login/queries.rs index 8301978..ad484ab 100644 --- a/src/login/queries.rs +++ b/src/login/queries.rs @@ -7,7 +7,6 @@ use ddnet_accounts_shared::client::credential_auth_token::CredentialAuthTokenOpe use ddnet_accounts_shared::client::login::CredentialAuthToken; use ddnet_accounts_shared::client::machine_id::MachineUid; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Row; use sqlx::Statement; @@ -27,19 +26,19 @@ pub struct CredentialAuthTokenData { #[async_trait] impl Query for CredentialAuthTokenQry<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/credential_auth_token_data.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.token.as_slice()) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(CredentialAuthTokenData { ty: TokenType::from_str( row.try_get("ty") @@ -63,19 +62,19 @@ pub struct InvalidateCredentialAuthToken<'a> { #[async_trait] impl Query<()> for InvalidateCredentialAuthToken<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/invalidate_credential_auth_token.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.token.as_slice()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -85,19 +84,19 @@ pub struct TryCreateAccount {} #[async_trait] impl Query<()> for TryCreateAccount { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_account.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -110,22 +109,22 @@ pub struct LinkAccountCredentialEmail<'a> { #[async_trait] impl Query<()> for LinkAccountCredentialEmail<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/link_credential_email.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement .query() .bind(self.account_id) .bind(self.email.as_str()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -138,19 +137,19 @@ pub struct LinkAccountCredentialSteam<'a> { #[async_trait] impl Query<()> for LinkAccountCredentialSteam<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/link_credential_steam.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.account_id).bind(self.steamid64) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -164,19 +163,19 @@ pub struct AccountIdFromLastInsert {} #[async_trait] impl Query for AccountIdFromLastInsert { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/account_id_from_last_insert.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AccountData { account_id: row .try_get("account_id") @@ -192,19 +191,19 @@ pub struct AccountIdFromEmail<'a> { #[async_trait] impl Query for AccountIdFromEmail<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/account_id_from_email.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.email.as_str()) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AccountData { account_id: row .try_get("account_id") @@ -220,19 +219,19 @@ pub struct AccountIdFromSteam<'a> { #[async_trait] impl Query for AccountIdFromSteam<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/account_id_from_steam.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.steamid64) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AccountData { account_id: row .try_get("account_id") @@ -250,23 +249,23 @@ pub struct CreateSession<'a> { #[async_trait] impl Query<()> for CreateSession<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/add_session.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement .query() .bind(self.account_id) .bind(self.pub_key.as_slice()) .bind(self.hw_id.as_slice()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/logout.rs b/src/logout.rs index 1da3034..fbebd81 100644 --- a/src/logout.rs +++ b/src/logout.rs @@ -3,7 +3,7 @@ pub mod queries; use std::sync::Arc; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ errors::{AccountServerRequestError, Empty}, @@ -11,7 +11,6 @@ use ddnet_accounts_shared::{ }, client::logout::LogoutRequest, }; -use sqlx::{Acquire, AnyPool}; use crate::shared::{Shared, CERT_MAX_AGE_DELTA, CERT_MIN_AGE_DELTA}; @@ -45,7 +44,7 @@ pub async fn logout(shared: Arc, pool: AnyPool, data: LogoutRequest) -> ); let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; // remove this session let qry = RemoveSession { @@ -53,8 +52,8 @@ pub async fn logout(shared: Arc, pool: AnyPool, data: LogoutRequest) -> hw_id: &data.account_data.hw_id, }; - qry.query(connection, &shared.db.logout_statement) - .execute(connection) + qry.query(&shared.db.logout_statement) + .execute(&mut connection) .await?; Ok(()) diff --git a/src/logout/queries.rs b/src/logout/queries.rs index 8195e27..c752e18 100644 --- a/src/logout/queries.rs +++ b/src/logout/queries.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::machine_id::MachineUid; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -14,22 +13,22 @@ pub struct RemoveSession<'a> { #[async_trait] impl Query<()> for RemoveSession<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/rem_session.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement .query() .bind(self.pub_key.as_slice()) .bind(self.hw_id.as_slice()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/logout_all.rs b/src/logout_all.rs index c5b4f21..b545b94 100644 --- a/src/logout_all.rs +++ b/src/logout_all.rs @@ -3,7 +3,7 @@ pub mod queries; use std::sync::Arc; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ errors::{AccountServerRequestError, Empty}, @@ -11,7 +11,6 @@ use ddnet_accounts_shared::{ }, client::logout_all::{IgnoreSession, LogoutAllRequest}, }; -use sqlx::{Acquire, AnyPool, Connection}; use crate::{ account_token::queries::{AccountTokenQry, InvalidateAccountToken}, @@ -41,10 +40,10 @@ pub async fn logout_all( data: LogoutAllRequest, ) -> anyhow::Result<()> { let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; connection - .transaction(|connection| { + .transaction(|mut connection| { Box::pin(async move { // token data let acc_token_qry = AccountTokenQry { @@ -52,8 +51,8 @@ pub async fn logout_all( }; let row = acc_token_qry - .query(connection, &shared.db.account_token_qry_statement) - .fetch_one(&mut **connection) + .query(&shared.db.account_token_qry_statement) + .fetch_one(&mut connection.con()) .await?; let token_data = AccountTokenQry::row_data(&row)?; @@ -62,8 +61,8 @@ pub async fn logout_all( let qry = InvalidateAccountToken { token: &data.account_token, }; - qry.query(connection, &shared.db.invalidate_account_token_statement) - .execute(&mut **connection) + qry.query(&shared.db.invalidate_account_token_statement) + .execute(&mut connection.con()) .await?; anyhow::ensure!( @@ -96,8 +95,8 @@ pub async fn logout_all( session_data: &session_data, }; - qry.query(connection, &shared.db.remove_sessions_except_statement) - .execute(&mut **connection) + qry.query(&shared.db.remove_sessions_except_statement) + .execute(&mut connection.con()) .await?; anyhow::Ok(()) diff --git a/src/logout_all/queries.rs b/src/logout_all/queries.rs index 42ba3b2..5de88e0 100644 --- a/src/logout_all/queries.rs +++ b/src/logout_all/queries.rs @@ -3,7 +3,6 @@ use axum::async_trait; use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::account_data::AccountDataForServer; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -15,16 +14,16 @@ pub struct RemoveSessionsExcept<'a> { #[async_trait] impl Query<()> for RemoveSessionsExcept<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/rem_sessions_except.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { let (key, hwid) = self .session_data .as_ref() @@ -37,7 +36,7 @@ impl Query<()> for RemoveSessionsExcept<'_> { .bind(key) .bind(hwid) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/main.rs b/src/main.rs index 2b5feef..d4fd450 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,7 @@ use credential_auth_token::{ credential_auth_token_email, credential_auth_token_steam, queries::AddCredentialAuthToken, }; use db::DbConnectionShared; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::account_server::{ errors::AccountServerRequestError, result::AccountServerReqResult, }; @@ -77,7 +77,8 @@ use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use shared::Shared; use sign::{queries::AuthAttempt, sign_request}; -use sqlx::{any::AnyPoolOptions, mysql::MySqlConnectOptions, Any, AnyPool, Pool}; +use sqlx::mysql::MySqlConnectOptions; +use sqlx::mysql::MySqlPoolOptions; use std::{ net::SocketAddr, num::NonZeroU32, @@ -243,32 +244,36 @@ struct Details { limitter: LimiterSettings, } -pub(crate) async fn prepare_db(details: &DbDetails) -> anyhow::Result> { +pub(crate) async fn prepare_db(details: &DbDetails) -> anyhow::Result { let is_localhost = details.host == "localhost" || details.host == "127.0.0.1" || details.host == "::1"; - Ok(AnyPoolOptions::new() - .max_connections(200) - .connect_with( - MySqlConnectOptions::new() - .charset("utf8mb4") - .host(&details.host) - .port(details.port) - .database(&details.database) - .username(&details.username) - .password(&details.password) - .ssl_mode(if !is_localhost { - sqlx::mysql::MySqlSslMode::Required - } else { - sqlx::mysql::MySqlSslMode::Preferred - }) - .ssl_ca(&details.ca_cert_path) - .into(), - ) - .await?) + + sqlx::any::install_default_drivers(); + Ok(AnyPool::MySql( + MySqlPoolOptions::new() + .max_connections(200) + .connect_with( + MySqlConnectOptions::new() + .charset("utf8mb4") + .host(&details.host) + .port(details.port) + .database(&details.database) + .username(&details.username) + .password(&details.password) + .ssl_mode(if !is_localhost { + sqlx::mysql::MySqlSslMode::Required + } else { + sqlx::mysql::MySqlSslMode::Preferred + }) + .ssl_ca(&details.ca_cert_path), + ) + .await?, + )) } -pub(crate) async fn prepare_statements(pool: &Pool) -> anyhow::Result { +pub(crate) async fn prepare_statements(pool: &AnyPool) -> anyhow::Result { let mut connection = pool.acquire().await?; + let mut connection = connection.acquire().await?; // now prepare the statements let credential_auth_token_statement = AddCredentialAuthToken::prepare(&mut connection).await?; @@ -369,7 +374,7 @@ pub(crate) async fn prepare_http( db: DbConnectionShared, email: EmailShared, steam: SteamShared, - pool: &Pool, + pool: &AnyPool, settings: &LimiterSettings, ) -> anyhow::Result<(TcpListener, Router, Arc)> { let keys = tokio::fs::read("signing_keys.json") @@ -673,7 +678,7 @@ pub(crate) async fn prepare_http( pub(crate) async fn prepare( details: &Details, -) -> anyhow::Result<(TcpListener, Router, Pool, Arc)> { +) -> anyhow::Result<(TcpListener, Router, AnyPool, Arc)> { // first connect to the database let pool = prepare_db(&details.db).await?; diff --git a/src/setup.rs b/src/setup.rs index 3d2e9a3..5726fa8 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,14 +1,13 @@ +use ddnet_account_sql::any::AnyConnection; +use ddnet_account_sql::any::AnyPool; use ddnet_account_sql::version::get_version; use ddnet_account_sql::version::set_version; -use sqlx::Acquire; -use sqlx::AnyConnection; -use sqlx::Connection; use sqlx::Executor; use sqlx::Statement; const VERSION_NAME: &str = "account-server"; -async fn setup_version1_mysql(con: &mut AnyConnection) -> anyhow::Result<()> { +async fn setup_version1_mysql(con: &mut sqlx::mysql::MySqlConnection) -> anyhow::Result<()> { // first create all statements (syntax check) let account = con.prepare(include_str!("setup/mysql/account.sql")).await?; let credential_email = con @@ -35,28 +34,28 @@ async fn setup_version1_mysql(con: &mut AnyConnection) -> anyhow::Result<()> { session.query().execute(&mut *con).await?; certs.query().execute(&mut *con).await?; - set_version(con, VERSION_NAME, 1).await?; + set_version(&mut AnyConnection::MySql(&mut *con), VERSION_NAME, 1).await?; Ok(()) } -pub async fn setup_version1(con: &mut AnyConnection) -> anyhow::Result<()> { - match con.kind() { - sqlx::any::AnyKind::MySql => setup_version1_mysql(con).await, +pub async fn setup_version1(con: &mut AnyConnection<'_>) -> anyhow::Result<()> { + match con { + AnyConnection::MySql(con) => setup_version1_mysql(con).await, } } -pub async fn setup(pool: &sqlx::AnyPool) -> anyhow::Result<()> { +pub async fn setup(pool: &AnyPool) -> anyhow::Result<()> { tokio::fs::create_dir_all("config").await?; let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; + let mut con = pool_con.acquire().await?; - con.transaction(|con| { + con.transaction(|mut con| { Box::pin(async move { - let version = get_version(con, VERSION_NAME).await?; + let version = get_version(&mut con.con(), VERSION_NAME).await?; if version < 1 { - setup_version1(&mut *con).await?; + setup_version1(&mut con.con()).await?; } anyhow::Ok(()) @@ -65,10 +64,7 @@ pub async fn setup(pool: &sqlx::AnyPool) -> anyhow::Result<()> { .await } -async fn delete_mysql(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - let mut pool_con = pool.acquire().await?; - let con = pool_con.acquire().await?; - +async fn delete_mysql(con: &mut sqlx::mysql::MySqlConnection) -> anyhow::Result<()> { // first create all statements (syntax check) // delete in reverse order to creating let session = con @@ -104,7 +100,7 @@ async fn delete_mysql(pool: &sqlx::AnyPool) -> anyhow::Result<()> { let account = account.query().execute(&mut *con).await; let certs = certs.query().execute(&mut *con).await; - let _ = set_version(con, VERSION_NAME, 0).await; + let _ = set_version(&mut AnyConnection::MySql(&mut *con), VERSION_NAME, 0).await; // handle errors at once session @@ -118,10 +114,12 @@ async fn delete_mysql(pool: &sqlx::AnyPool) -> anyhow::Result<()> { Ok(()) } -pub async fn delete(pool: &sqlx::AnyPool) -> anyhow::Result<()> { - match pool.any_kind() { - sqlx::any::AnyKind::MySql => { - let _ = delete_mysql(pool).await; +pub async fn delete(pool: &AnyPool) -> anyhow::Result<()> { + let mut con = pool.acquire().await?; + let con = con.acquire().await?; + match con { + AnyConnection::MySql(con) => { + let _ = delete_mysql(con).await; } } diff --git a/src/sign.rs b/src/sign.rs index dabec6e..aa68766 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -3,7 +3,7 @@ pub mod queries; use std::{str::FromStr, sync::Arc, time::Duration}; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ cert_account_ext::{AccountCertData, AccountCertExt}, @@ -14,7 +14,6 @@ use ddnet_accounts_shared::{ client::sign::SignRequest, }; use p256::ecdsa::DerSignature; -use sqlx::{Acquire, AnyPool}; use x509_cert::builder::Builder; use x509_cert::der::Encode; use x509_cert::{ @@ -58,12 +57,12 @@ pub async fn sign( ); let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; let qry = AuthAttempt { data: &data }; let row = qry - .query(connection, &shared.db.auth_attempt_statement) - .fetch_one(connection) + .query(&shared.db.auth_attempt_statement) + .fetch_one(&mut connection) .await?; let auth_data = AuthAttempt::row_data(&row)?; diff --git a/src/sign/queries.rs b/src/sign/queries.rs index 058d1bf..9cfe134 100644 --- a/src/sign/queries.rs +++ b/src/sign/queries.rs @@ -1,7 +1,6 @@ use ddnet_account_sql::query::Query; use ddnet_accounts_shared::client::sign::SignRequest; use ddnet_accounts_types::account_id::AccountId; -use sqlx::any::AnyRow; use sqlx::types::chrono::DateTime; use sqlx::types::chrono::Utc; use sqlx::Executor; @@ -22,20 +21,20 @@ pub struct AuthAttemptData { #[async_trait::async_trait] impl Query for AuthAttempt<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection.prepare(include_str!("mysql/auth.sql")).await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement .query() .bind(self.data.account_data.public_key.as_bytes().as_slice()) .bind(self.data.account_data.hw_id.as_slice()) } - fn row_data(row: &AnyRow) -> anyhow::Result { + fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result { Ok(AuthAttemptData { account_id: row.try_get("account_id")?, creation_date: row.try_get("create_time")?, diff --git a/src/tests/types.rs b/src/tests/types.rs index 13fe9ec..ec10272 100644 --- a/src/tests/types.rs +++ b/src/tests/types.rs @@ -1,10 +1,10 @@ use std::{num::NonZeroU32, sync::Arc, time::Duration}; use axum::{extract::Query, response::IntoResponse, routing::get, Router}; +use ddnet_account_sql::any::AnyPool; use lettre::SmtpTransport; use parking_lot::Mutex; use serde::Deserialize; -use sqlx::{Any, Pool}; use tokio::{net::TcpSocket, task::JoinHandle}; use crate::{ @@ -14,7 +14,7 @@ use crate::{ steam::{self, SteamHook, SteamShared}, }; -pub async fn test_setup() -> anyhow::Result> { +pub async fn test_setup() -> anyhow::Result { prepare_db(&crate::DbDetails { host: "localhost".into(), port: 3306, @@ -28,7 +28,7 @@ pub async fn test_setup() -> anyhow::Result> { pub struct TestAccServer { pub(crate) server: JoinHandle>, - pub(crate) pool: Pool, + pub(crate) pool: AnyPool, pub(crate) shared: Arc, pub(crate) steam: JoinHandle>, } @@ -221,12 +221,12 @@ impl TestAccServer { } pub struct TestGameServer { - pool: Pool, + pool: AnyPool, pub(crate) game_server_data: Arc, } impl TestGameServer { - pub(crate) async fn new(pool: &Pool) -> anyhow::Result { + pub(crate) async fn new(pool: &AnyPool) -> anyhow::Result { // make sure the tables are gone let _ = ddnet_account_game_server::setup::delete(pool).await; ddnet_account_game_server::setup::setup(pool).await?; diff --git a/src/unlink_credential.rs b/src/unlink_credential.rs index dc64e06..c758359 100644 --- a/src/unlink_credential.rs +++ b/src/unlink_credential.rs @@ -3,7 +3,7 @@ pub mod queries; use std::{str::FromStr, sync::Arc}; use axum::Json; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use ddnet_accounts_shared::{ account_server::{ errors::{AccountServerRequestError, Empty}, @@ -12,7 +12,6 @@ use ddnet_accounts_shared::{ client::unlink_credential::UnlinkCredentialRequest, }; use queries::{UnlinkCredentialByEmail, UnlinkCredentialBySteam}; -use sqlx::{Acquire, AnyPool, Connection}; use crate::{ login::get_and_invalidate_credential_auth_token, @@ -40,15 +39,15 @@ pub async fn unlink_credential( data: UnlinkCredentialRequest, ) -> anyhow::Result<()> { let mut connection = pool.acquire().await?; - let connection = connection.acquire().await?; + let mut connection = connection.acquire().await?; connection - .transaction(|connection| { + .transaction(|mut connection| { Box::pin(async move { let token_data = get_and_invalidate_credential_auth_token( &shared, data.credential_auth_token, - connection, + &mut connection.con(), ) .await? .ok_or_else(|| anyhow::anyhow!("Credential auth token is invalid/expired."))?; @@ -64,8 +63,8 @@ pub async fn unlink_credential( // remove the current email, if exists. let qry = UnlinkCredentialByEmail { email: &email }; - qry.query(connection, &shared.db.unlink_credential_by_email_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_by_email_statement) + .execute(&mut connection.con()) .await? .rows_affected() } @@ -76,8 +75,8 @@ pub async fn unlink_credential( steamid64: &steamid64, }; - qry.query(connection, &shared.db.unlink_credential_by_steam_statement) - .execute(&mut **connection) + qry.query(&shared.db.unlink_credential_by_steam_statement) + .execute(&mut connection.con()) .await? .rows_affected() } diff --git a/src/unlink_credential/queries.rs b/src/unlink_credential/queries.rs index a382438..b243a45 100644 --- a/src/unlink_credential/queries.rs +++ b/src/unlink_credential/queries.rs @@ -1,7 +1,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -12,19 +11,19 @@ pub struct UnlinkCredentialByEmail<'a> { #[async_trait] impl Query<()> for UnlinkCredentialByEmail<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/unlink_credential_email.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.email.as_str()) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -36,19 +35,19 @@ pub struct UnlinkCredentialBySteam<'a> { #[async_trait] impl Query<()> for UnlinkCredentialBySteam<'_> { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/unlink_credential_steam.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query().bind(self.steamid64) } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } diff --git a/src/update.rs b/src/update.rs index 3553bc3..88be7b0 100644 --- a/src/update.rs +++ b/src/update.rs @@ -1,8 +1,7 @@ use std::{sync::Arc, time::Duration}; -use ddnet_account_sql::query::Query; +use ddnet_account_sql::{any::AnyPool, query::Query}; use queries::{CleanupAccountTokens, CleanupCerts, CleanupCredentialAuthTokens}; -use sqlx::{Acquire, AnyPool, Executor}; use crate::{email::EmailShared, email_limit, ip_limit, shared::Shared}; @@ -10,26 +9,23 @@ pub mod queries; pub async fn update_impl(pool: &AnyPool, shared: &Arc) { if let Ok(mut connection) = pool.acquire().await { - if let Ok(connection) = connection.acquire().await { + if let Ok(mut connection) = connection.acquire().await { // cleanup credential auth tokens - let _ = connection - .execute(CleanupCredentialAuthTokens {}.query( - connection, - &shared.db.cleanup_credential_auth_tokens_statement, - )) + let _ = CleanupCredentialAuthTokens {} + .query(&shared.db.cleanup_credential_auth_tokens_statement) + .execute(&mut connection) .await; // cleanup account tokens - let _ = connection - .execute( - CleanupAccountTokens {} - .query(connection, &shared.db.cleanup_account_tokens_statement), - ) + let _ = CleanupAccountTokens {} + .query(&shared.db.cleanup_account_tokens_statement) + .execute(&mut connection) .await; // cleanup certs - let _ = connection - .execute(CleanupCerts {}.query(connection, &shared.db.cleanup_certs_statement)) + let _ = CleanupCerts {} + .query(&shared.db.cleanup_certs_statement) + .execute(&mut connection) .await; } } diff --git a/src/update/queries.rs b/src/update/queries.rs index 68bec7b..920e99f 100644 --- a/src/update/queries.rs +++ b/src/update/queries.rs @@ -1,7 +1,6 @@ use anyhow::anyhow; use axum::async_trait; use ddnet_account_sql::query::Query; -use sqlx::any::AnyRow; use sqlx::Executor; use sqlx::Statement; @@ -10,19 +9,19 @@ pub struct CleanupCredentialAuthTokens {} #[async_trait] impl Query<()> for CleanupCredentialAuthTokens { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/cleanup_credential_auth_tokens.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -32,19 +31,19 @@ pub struct CleanupAccountTokens {} #[async_trait] impl Query<()> for CleanupAccountTokens { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/cleanup_account_tokens.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } } @@ -54,19 +53,19 @@ pub struct CleanupCerts {} #[async_trait] impl Query<()> for CleanupCerts { async fn prepare_mysql( - connection: &mut sqlx::AnyConnection, - ) -> anyhow::Result> { + connection: &mut sqlx::mysql::MySqlConnection, + ) -> anyhow::Result> { Ok(connection .prepare(include_str!("mysql/cleanup_certs.sql")) .await?) } fn query_mysql<'b>( &'b self, - statement: &'b sqlx::any::AnyStatement<'static>, - ) -> sqlx::query::Query<'b, sqlx::Any, sqlx::any::AnyArguments<'b>> { + statement: &'b sqlx::mysql::MySqlStatement<'static>, + ) -> sqlx::query::Query<'b, sqlx::MySql, sqlx::mysql::MySqlArguments> { statement.query() } - fn row_data(_row: &AnyRow) -> anyhow::Result<()> { + fn row_data_mysql(_row: &sqlx::mysql::MySqlRow) -> anyhow::Result<()> { Err(anyhow!("Row data is not supported")) } }