diff --git a/Cargo.lock b/Cargo.lock index e914ef143..85117faab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,6 +521,22 @@ dependencies = [ "zbus", ] +[[package]] +name = "astral-tokio-tar" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec179a06c1769b1e42e1e2cbe74c7dcdb3d6383c838454d063eaac5bbb7ebbe5" +dependencies = [ + "filetime", + "futures-core", + "libc", + "portable-atomic", + "rustc-hash", + "tokio", + "tokio-stream", + "xattr", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -671,6 +687,28 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "async-stripe" version = "0.41.0" @@ -892,6 +930,49 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.76" @@ -1066,6 +1147,83 @@ dependencies = [ "piper", ] +[[package]] +name = "bollard" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87a52479c9237eb04047ddb94788c41ca0d26eaff8b697ecfbb4c32f7fdc3b1b" +dependencies = [ + "async-stream", + "base64 0.22.1", + "bitflags 2.9.4", + "bollard-buildkit-proto", + "bollard-stubs", + "bytes", + "chrono", + "futures-core", + "futures-util", + "hex", + "home", + "http 1.3.1", + "http-body-util", + "hyper 1.7.0", + "hyper-named-pipe", + "hyper-rustls 0.27.7", + "hyper-util", + "hyperlocal", + "log", + "num", + "pin-project-lite", + "rand 0.9.2", + "rustls 0.23.32", + "rustls-native-certs 0.8.1", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tokio-util", + "tonic 0.14.2", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-buildkit-proto" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a885520bf6249ab931a764ffdb87b0ceef48e6e7d807cfdb21b751e086e1ad" +dependencies = [ + "prost 0.14.3", + "prost-types", + "tonic 0.14.2", + "tonic-prost", + "ureq", +] + +[[package]] +name = "bollard-stubs" +version = "1.49.1-rc.28.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5731fe885755e92beff1950774068e0cae67ea6ec7587381536fca84f1779623" +dependencies = [ + "base64 0.22.1", + "bollard-buildkit-proto", + "bytes", + "chrono", + "prost 0.14.3", + "serde", + "serde_json", + "serde_repr", + "serde_with", +] + [[package]] name = "borsh" version = "1.5.7" @@ -2378,6 +2536,17 @@ dependencies = [ "const-random", ] +[[package]] +name = "docker_credential" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d89dfcba45b4afad7450a99b39e751590463e45c04728cf555d36bb66940de8" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + [[package]] name = "document-features" version = "0.2.11" @@ -2679,6 +2848,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "etcetera" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.59.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -3801,6 +3981,21 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper 1.7.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -3835,6 +4030,19 @@ dependencies = [ "webpki-roots 1.0.3", ] +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.7.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -3877,6 +4085,21 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper 1.7.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -4566,6 +4789,7 @@ dependencies = [ "sha2", "spdx", "sqlx", + "sqlx-tracing", "strum", "thiserror 2.0.17", "tikv-jemalloc-ctl", @@ -4888,6 +5112,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "maxminddb" version = "0.26.0" @@ -5873,6 +6103,124 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "opentelemetry-appender-tracing" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68f63eca5fad47e570e00e893094fc17be959c80c79a7d6ec1abdd5ae6ffc16" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry-http" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d" +dependencies = [ + "async-trait", + "bytes", + "http 1.3.1", + "opentelemetry", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" +dependencies = [ + "http 1.3.1", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost 0.13.5", + "reqwest", + "thiserror 2.0.17", + "tokio", + "tonic 0.13.1", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost 0.13.5", + "tonic 0.13.1", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2" + +[[package]] +name = "opentelemetry-testing" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562407eb254fea88076c8a410a733a8ee2075fd9c7fbde3da2a03d29e2cef104" +dependencies = [ + "anyhow", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "serde", + "serde_json", + "serial_test", + "tempfile", + "testcontainers", + "tokio", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "rand 0.9.2", + "serde_json", + "thiserror 2.0.17", + "tokio", + "tokio-stream", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5997,6 +6345,31 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "parse-display" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" +dependencies = [ + "parse-display-derive", + "regex", + "regex-syntax", +] + +[[package]] +name = "parse-display-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "regex-syntax", + "structmeta", + "syn 2.0.106", +] + [[package]] name = "parse-size" version = "1.1.0" @@ -6384,7 +6757,7 @@ dependencies = [ "inferno", "num", "paste", - "prost", + "prost 0.13.5", ] [[package]] @@ -6590,7 +6963,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.13.5", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive 0.14.3", ] [[package]] @@ -6606,6 +6989,28 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost 0.14.3", +] + [[package]] name = "protobuf" version = "3.7.2" @@ -7633,6 +8038,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + [[package]] name = "schannel" version = "0.1.28" @@ -7724,6 +8138,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + [[package]] name = "seahash" version = "4.1.0" @@ -8170,6 +8590,32 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "serial_test" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +dependencies = [ + "futures-executor", + "futures-util", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "serialize-to-javascript" version = "0.1.2" @@ -8576,7 +9022,7 @@ dependencies = [ "chrono", "crc", "dotenvy", - "etcetera", + "etcetera 0.8.0", "futures-channel", "futures-core", "futures-util", @@ -8629,6 +9075,20 @@ dependencies = [ "uuid 1.18.1", ] +[[package]] +name = "sqlx-tracing" +version = "0.2.0" +dependencies = [ + "derive_more 2.0.1", + "futures", + "opentelemetry", + "opentelemetry-testing", + "sqlx", + "testcontainers", + "tokio", + "tracing", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -9405,6 +9865,35 @@ dependencies = [ "winapi", ] +[[package]] +name = "testcontainers" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3ac71069f20ecfa60c396316c283fbf35e6833a53dff551a31b5458da05edc" +dependencies = [ + "astral-tokio-tar", + "async-trait", + "bollard", + "bytes", + "docker_credential", + "either", + "etcetera 0.10.0", + "futures", + "log", + "memchr", + "parse-display", + "pin-project-lite", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tokio-util", + "ulid", + "url", +] + [[package]] name = "theseus" version = "1.0.0-local" @@ -9871,6 +10360,72 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +[[package]] +name = "tonic" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost 0.13.5", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.1", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +dependencies = [ + "bytes", + "prost 0.14.3", + "tonic 0.14.2", +] + [[package]] name = "totp-rs" version = "5.7.0" @@ -9893,11 +10448,15 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", + "indexmap 2.11.4", "pin-project-lite", + "slab", "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -10013,6 +10572,24 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + [[package]] name = "tracing-subscriber" version = "0.3.20" @@ -10108,6 +10685,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "ulid" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" +dependencies = [ + "rand 0.9.2", + "web-time", +] + [[package]] name = "uname" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index 4d8fbcc54..5b52543f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -164,6 +164,7 @@ sha2 = "0.10.9" shlex = "1.3.0" spdx = "0.12.0" sqlx = { version = "0.8.6", default-features = false } +sqlx-tracing = { path = "packages/sqlx-tracing" } strum = "0.27.2" sysinfo = { version = "0.37.2", default-features = false } tar = "0.4.44" @@ -269,4 +270,5 @@ codegen-units = 1 # Compile crates one after another so the compiler can optimi # Specific profile for labrinth production builds [profile.release-labrinth] inherits = "release" +strip = false # Keep debug symbols for Sentry panic = "unwind" # Don't exit the whole app on panic in production diff --git a/apps/labrinth/.sqlx/query-1adbd24d815107e13bc1440c7a8f4eeff66ab4165a9f4980032e114db4dc1286.json b/apps/labrinth/.sqlx/query-1adbd24d815107e13bc1440c7a8f4eeff66ab4165a9f4980032e114db4dc1286.json new file mode 100644 index 000000000..921f7f92d --- /dev/null +++ b/apps/labrinth/.sqlx/query-1adbd24d815107e13bc1440c7a8f4eeff66ab4165a9f4980032e114db4dc1286.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n id,\n status AS \"status: PayoutStatus\"\n FROM payouts\n ORDER BY id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "status: PayoutStatus", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false + ] + }, + "hash": "1adbd24d815107e13bc1440c7a8f4eeff66ab4165a9f4980032e114db4dc1286" +} diff --git a/apps/labrinth/.sqlx/query-79c73369365ed7a09f4f48a87605d22db4a49ab5fd9943b54865448d0e9a8d67.json b/apps/labrinth/.sqlx/query-ad48051c9ac8f233ebfeeebec834ff96df8525a6ed872be7a64b8f349b36b276.json similarity index 68% rename from apps/labrinth/.sqlx/query-79c73369365ed7a09f4f48a87605d22db4a49ab5fd9943b54865448d0e9a8d67.json rename to apps/labrinth/.sqlx/query-ad48051c9ac8f233ebfeeebec834ff96df8525a6ed872be7a64b8f349b36b276.json index dd98633e5..99373fb6a 100644 --- a/apps/labrinth/.sqlx/query-79c73369365ed7a09f4f48a87605d22db4a49ab5fd9943b54865448d0e9a8d67.json +++ b/apps/labrinth/.sqlx/query-ad48051c9ac8f233ebfeeebec834ff96df8525a6ed872be7a64b8f349b36b276.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO loader_field_enum_values (enum_id, value, created, metadata)\n VALUES ($1, $2, COALESCE($3, timezone('utc', now())), $4)\n ON CONFLICT (enum_id, value) DO UPDATE\n SET metadata = jsonb_set(\n COALESCE(loader_field_enum_values.metadata, $4),\n '{type}', \n COALESCE($4->'type', loader_field_enum_values.metadata->'type')\n ),\n created = COALESCE($3, loader_field_enum_values.created)\n RETURNING id\n ", + "query": "\n INSERT INTO loader_field_enum_values (enum_id, value, created, metadata)\n VALUES ($1, $2, COALESCE($3, timezone('utc', now())), $4)\n ON CONFLICT (enum_id, value) DO UPDATE\n SET metadata = jsonb_set(\n COALESCE(loader_field_enum_values.metadata, $4),\n '{type}',\n COALESCE($4->'type', loader_field_enum_values.metadata->'type')\n ),\n created = COALESCE($3, loader_field_enum_values.created)\n RETURNING id\n ", "describe": { "columns": [ { @@ -21,5 +21,5 @@ false ] }, - "hash": "79c73369365ed7a09f4f48a87605d22db4a49ab5fd9943b54865448d0e9a8d67" + "hash": "ad48051c9ac8f233ebfeeebec834ff96df8525a6ed872be7a64b8f349b36b276" } diff --git a/apps/labrinth/.sqlx/query-b92b5bb7d179c4fcdbc45600ccfd2402f52fea71e27b08e7926fcc2a9e62c0f3.json b/apps/labrinth/.sqlx/query-b92b5bb7d179c4fcdbc45600ccfd2402f52fea71e27b08e7926fcc2a9e62c0f3.json new file mode 100644 index 000000000..89bd8147d --- /dev/null +++ b/apps/labrinth/.sqlx/query-b92b5bb7d179c4fcdbc45600ccfd2402f52fea71e27b08e7926fcc2a9e62c0f3.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT status AS \"status: PayoutStatus\" FROM payouts WHERE id = 1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "status: PayoutStatus", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false + ] + }, + "hash": "b92b5bb7d179c4fcdbc45600ccfd2402f52fea71e27b08e7926fcc2a9e62c0f3" +} diff --git a/apps/labrinth/.sqlx/query-cd5ccd618fb3cc41646a6de86f9afedb074492b4ec7f2457c14113f5fd13aa02.json b/apps/labrinth/.sqlx/query-cd5ccd618fb3cc41646a6de86f9afedb074492b4ec7f2457c14113f5fd13aa02.json new file mode 100644 index 000000000..469c30168 --- /dev/null +++ b/apps/labrinth/.sqlx/query-cd5ccd618fb3cc41646a6de86f9afedb074492b4ec7f2457c14113f5fd13aa02.json @@ -0,0 +1,18 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO payouts (id, method, platform_id, status, user_id, amount, created)\n VALUES ($1, $2, $3, $4, $5, 10.0, NOW())\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Text", + "Text", + "Varchar", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "cd5ccd618fb3cc41646a6de86f9afedb074492b4ec7f2457c14113f5fd13aa02" +} diff --git a/apps/labrinth/.sqlx/query-cec4240c7c848988b3dfd13e3f8e5c93783c7641b019fdb698a1ec0be1393606.json b/apps/labrinth/.sqlx/query-cec4240c7c848988b3dfd13e3f8e5c93783c7641b019fdb698a1ec0be1393606.json new file mode 100644 index 000000000..52e020ebf --- /dev/null +++ b/apps/labrinth/.sqlx/query-cec4240c7c848988b3dfd13e3f8e5c93783c7641b019fdb698a1ec0be1393606.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO payouts (id, method, platform_id, status, user_id, amount, created)\n VALUES ($1, $2, NULL, $3, $4, 10.00, NOW())\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Text", + "Varchar", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "cec4240c7c848988b3dfd13e3f8e5c93783c7641b019fdb698a1ec0be1393606" +} diff --git a/apps/labrinth/Cargo.toml b/apps/labrinth/Cargo.toml index aa6bdb0b3..76cbff499 100644 --- a/apps/labrinth/Cargo.toml +++ b/apps/labrinth/Cargo.toml @@ -27,7 +27,6 @@ async-stripe = { workspace = true, features = [ "connect", "webhook-events", ] } -derive_more = { workspace = true, features = ["deref", "deref_mut"]} async-trait = { workspace = true } base64 = { workspace = true } bitflags = { workspace = true } @@ -41,6 +40,7 @@ color-thief = { workspace = true } const_format = { workspace = true } dashmap = { workspace = true } deadpool-redis.workspace = true +derive_more = { workspace = true, features = ["deref", "deref_mut"] } dotenvy = { workspace = true } either = { workspace = true } eyre = { workspace = true } @@ -112,6 +112,7 @@ sqlx = { workspace = true, features = [ "rust_decimal", "tls-rustls-aws-lc-rs", ] } +sqlx-tracing = { workspace = true, features = ["postgres"] } strum = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "sync"] } diff --git a/apps/labrinth/src/auth/checks.rs b/apps/labrinth/src/auth/checks.rs index f56036df8..329e07104 100644 --- a/apps/labrinth/src/auth/checks.rs +++ b/apps/labrinth/src/auth/checks.rs @@ -1,4 +1,5 @@ use crate::database; +use crate::database::PgPool; use crate::database::models::project_item::ProjectQueryResult; use crate::database::models::version_item::VersionQueryResult; use crate::database::models::{DBCollection, DBOrganization, DBTeamMember}; @@ -8,7 +9,6 @@ use crate::models::users::User; use crate::routes::ApiError; use futures::TryStreamExt; use itertools::Itertools; -use sqlx::PgPool; pub trait ValidateAuthorized { fn validate_authorized( diff --git a/apps/labrinth/src/auth/oauth/mod.rs b/apps/labrinth/src/auth/oauth/mod.rs index 5a5d54670..d3fc5df6e 100644 --- a/apps/labrinth/src/auth/oauth/mod.rs +++ b/apps/labrinth/src/auth/oauth/mod.rs @@ -3,6 +3,7 @@ use std::fmt::Write; use crate::auth::get_user_from_headers; use crate::auth::oauth::uris::{OAuthRedirectUris, ValidatedRedirectUri}; use crate::auth::validate::extract_authorization_header; +use crate::database::PgPool; use crate::database::models::flow_item::DBFlow; use crate::database::models::oauth_client_authorization_item::DBOAuthClientAuthorization; use crate::database::models::oauth_client_item::DBOAuthClient; @@ -24,7 +25,6 @@ use rand::distributions::Alphanumeric; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha20Rng; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgPool; use self::errors::{OAuthError, OAuthErrorType}; @@ -288,7 +288,7 @@ pub async fn request_token( client_id, user_id, } - .insert(&mut *transaction) + .insert(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/auth/validate.rs b/apps/labrinth/src/auth/validate.rs index 97abe100f..fe3644ebd 100644 --- a/apps/labrinth/src/auth/validate.rs +++ b/apps/labrinth/src/auth/validate.rs @@ -18,7 +18,7 @@ pub async fn get_maybe_user_from_headers<'a, E>( required_scopes: Scopes, ) -> Result, AuthenticationError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { if !req.headers().contains_key(AUTHORIZATION) { return Ok(None); @@ -52,7 +52,7 @@ pub async fn get_full_user_from_headers<'a, E>( required_scopes: Scopes, ) -> Result<(Scopes, DBUser), AuthenticationError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let (scopes, db_user) = get_user_record_from_bearer_token( req, @@ -80,7 +80,7 @@ pub async fn get_user_from_headers<'a, E>( required_scopes: Scopes, ) -> Result<(Scopes, User), AuthenticationError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let (scopes, db_user) = get_full_user_from_headers( req, @@ -102,7 +102,7 @@ pub async fn get_user_record_from_bearer_token<'a, 'b, E>( session_queue: &AuthQueue, ) -> Result, AuthenticationError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let token = if let Some(token) = token { token @@ -227,7 +227,7 @@ pub async fn check_is_moderator_from_headers<'a, 'b, E>( required_scopes: Scopes, ) -> Result where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let user = get_user_from_headers( req, diff --git a/apps/labrinth/src/background_task.rs b/apps/labrinth/src/background_task.rs index 4f4bb3469..1783e36e2 100644 --- a/apps/labrinth/src/background_task.rs +++ b/apps/labrinth/src/background_task.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::queue::billing::{index_billing, index_subscriptions}; use crate::queue::email::EmailQueue; @@ -10,7 +11,6 @@ use crate::search::indexing::index_projects; use crate::util::anrok; use crate::{database, search}; use clap::ValueEnum; -use sqlx::Postgres; use tracing::{error, info, warn}; #[derive(ValueEnum, Debug, Copy, Clone, PartialEq, Eq)] @@ -31,8 +31,8 @@ impl BackgroundTask { #[allow(clippy::too_many_arguments)] pub async fn run( self, - pool: sqlx::PgPool, - ro_pool: sqlx::PgPool, + pool: PgPool, + ro_pool: PgPool, redis_pool: RedisPool, search_config: search::SearchConfig, clickhouse: clickhouse::Client, @@ -104,7 +104,7 @@ pub async fn run_email(email_queue: EmailQueue) { } } -pub async fn update_bank_balances(pool: sqlx::Pool) { +pub async fn update_bank_balances(pool: PgPool) { let payouts_queue = PayoutsQueue::new(); match insert_bank_balances_and_webhook(&payouts_queue, &pool).await { @@ -120,7 +120,7 @@ pub async fn run_migrations() { } pub async fn index_search( - ro_pool: sqlx::PgPool, + ro_pool: PgPool, redis_pool: RedisPool, search_config: search::SearchConfig, ) { @@ -132,7 +132,7 @@ pub async fn index_search( info!("Done indexing local database"); } -pub async fn release_scheduled(pool: sqlx::Pool) { +pub async fn release_scheduled(pool: PgPool) { info!("Releasing scheduled versions/projects!"); let projects_results = sqlx::query!( @@ -168,10 +168,7 @@ pub async fn release_scheduled(pool: sqlx::Pool) { info!("Finished releasing scheduled versions/projects"); } -pub async fn update_versions( - pool: sqlx::Pool, - redis_pool: RedisPool, -) { +pub async fn update_versions(pool: PgPool, redis_pool: RedisPool) { info!("Indexing game versions list from Mojang"); let result = version_updater::update_versions(&pool, &redis_pool).await; if let Err(e) = result { @@ -181,7 +178,7 @@ pub async fn update_versions( } pub async fn payouts( - pool: sqlx::Pool, + pool: PgPool, clickhouse: clickhouse::Client, redis_pool: RedisPool, ) { @@ -209,10 +206,7 @@ pub async fn payouts( info!("Done running payouts"); } -pub async fn sync_payout_statuses( - pool: sqlx::Pool, - mural: muralpay::Client, -) { +pub async fn sync_payout_statuses(pool: PgPool, mural: muralpay::Client) { // Mural sets a max limit of 100 for search payouts endpoint const LIMIT: u32 = 100; @@ -241,11 +235,11 @@ pub async fn sync_payout_statuses( mod version_updater { use std::sync::LazyLock; + use crate::database::PgPool; use crate::database::models::legacy_loader_fields::MinecraftGameVersion; use crate::database::redis::RedisPool; use chrono::{DateTime, Utc}; use serde::Deserialize; - use sqlx::Postgres; use thiserror::Error; use tracing::warn; @@ -273,7 +267,7 @@ mod version_updater { } pub async fn update_versions( - pool: &sqlx::Pool, + pool: &PgPool, redis: &RedisPool, ) -> Result<(), VersionIndexingError> { let input = reqwest::get( diff --git a/apps/labrinth/src/database/mod.rs b/apps/labrinth/src/database/mod.rs index dce09ad57..582cdceaf 100644 --- a/apps/labrinth/src/database/mod.rs +++ b/apps/labrinth/src/database/mod.rs @@ -5,6 +5,6 @@ pub use models::DBImage; pub use models::DBProject; pub use models::DBVersion; pub use postgres_database::{ - MIGRATOR, ReadOnlyPgPool, check_for_migrations, connect_all, - register_and_set_metrics, + Acquire, Executor, MIGRATOR, PgPool, PgTransaction, ReadOnlyPgPool, + check_for_migrations, connect_all, register_and_set_metrics, }; diff --git a/apps/labrinth/src/database/models/affiliate_code_item.rs b/apps/labrinth/src/database/models/affiliate_code_item.rs index 8ef5ca09d..b06e38c3d 100644 --- a/apps/labrinth/src/database/models/affiliate_code_item.rs +++ b/apps/labrinth/src/database/models/affiliate_code_item.rs @@ -15,7 +15,7 @@ pub struct DBAffiliateCode { impl DBAffiliateCode { pub async fn get_by_id( id: DBAffiliateCodeId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let record = sqlx::query!( "SELECT id, created_at, created_by, affiliate, source_name @@ -36,7 +36,7 @@ impl DBAffiliateCode { pub async fn get_by_affiliate( affiliate: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let records = sqlx::query!( "SELECT id, created_at, created_by, affiliate, source_name @@ -62,7 +62,7 @@ impl DBAffiliateCode { pub async fn insert( &self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { sqlx::query!( "INSERT INTO affiliate_codes (id, created_at, created_by, affiliate, source_name) @@ -80,7 +80,7 @@ impl DBAffiliateCode { pub async fn remove( id: DBAffiliateCodeId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let result = sqlx::query!( "DELETE FROM affiliate_codes WHERE id = $1", @@ -99,7 +99,7 @@ impl DBAffiliateCode { pub async fn update_source_name( id: DBAffiliateCodeId, source_name: &str, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result { let result = sqlx::query!( "UPDATE affiliate_codes SET source_name = $1 WHERE id = $2", @@ -113,7 +113,7 @@ impl DBAffiliateCode { } pub async fn get_all( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let records = sqlx::query!( "SELECT id, created_at, created_by, affiliate, source_name diff --git a/apps/labrinth/src/database/models/categories.rs b/apps/labrinth/src/database/models/categories.rs index 18a18b83e..44650d76d 100644 --- a/apps/labrinth/src/database/models/categories.rs +++ b/apps/labrinth/src/database/models/categories.rs @@ -44,7 +44,7 @@ impl Category { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -70,7 +70,7 @@ impl Category { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -91,7 +91,7 @@ impl Category { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -140,7 +140,7 @@ impl LinkPlatform { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -160,7 +160,7 @@ impl LinkPlatform { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -209,7 +209,7 @@ impl ReportType { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -229,7 +229,7 @@ impl ReportType { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -274,7 +274,7 @@ impl ProjectType { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -294,7 +294,7 @@ impl ProjectType { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; diff --git a/apps/labrinth/src/database/models/charge_item.rs b/apps/labrinth/src/database/models/charge_item.rs index fea02c0bb..1f5f29229 100644 --- a/apps/labrinth/src/database/models/charge_item.rs +++ b/apps/labrinth/src/database/models/charge_item.rs @@ -1,3 +1,4 @@ +use crate::database::PgTransaction; use crate::database::models::{ DBChargeId, DBProductPriceId, DBUserId, DBUserSubscriptionId, DatabaseError, }; @@ -123,7 +124,7 @@ macro_rules! select_charges_with_predicate { impl DBCharge { pub async fn upsert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { sqlx::query!( r#" @@ -173,7 +174,7 @@ impl DBCharge { self.tax_transaction_version, self.tax_platform_accounting_time, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(self.id) @@ -181,7 +182,7 @@ impl DBCharge { pub async fn get( id: DBChargeId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let id = id.0; let res = select_charges_with_predicate!("WHERE id = $1", id) @@ -193,7 +194,7 @@ impl DBCharge { pub async fn get_from_user( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let user_id = user_id.0; let res = select_charges_with_predicate!( @@ -211,7 +212,7 @@ impl DBCharge { pub async fn get_children( charge_id: DBChargeId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let charge_id = charge_id.0; let res = select_charges_with_predicate!( @@ -229,7 +230,7 @@ impl DBCharge { pub async fn get_open_subscription( user_subscription_id: DBUserSubscriptionId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let user_subscription_id = user_subscription_id.0; let res = select_charges_with_predicate!( @@ -246,7 +247,7 @@ impl DBCharge { } pub async fn get_chargeable( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let charge_type = ChargeType::Subscription.as_str(); let res = select_charges_with_predicate!( @@ -270,7 +271,7 @@ impl DBCharge { } pub async fn get_unprovision( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let charge_type = ChargeType::Subscription.as_str(); let res = select_charges_with_predicate!( @@ -297,7 +298,7 @@ impl DBCharge { } pub async fn get_cancellable( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let charge_type = ChargeType::Subscription.as_str(); let res = select_charges_with_predicate!( @@ -327,7 +328,7 @@ impl DBCharge { /// /// This also locks the charges. pub async fn get_updateable_lock( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, limit: i64, ) -> Result, DatabaseError> { let res = select_charges_with_predicate!( @@ -358,7 +359,7 @@ impl DBCharge { /// /// Charges are locked. pub async fn get_missing_tax_identifier_lock( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, offset: i64, limit: i64, ) -> Result, DatabaseError> { @@ -387,7 +388,7 @@ impl DBCharge { pub async fn remove( id: DBChargeId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -396,7 +397,7 @@ impl DBCharge { ", id.0 as i64 ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) diff --git a/apps/labrinth/src/database/models/collection_item.rs b/apps/labrinth/src/database/models/collection_item.rs index d82a1ae26..5ca827a83 100644 --- a/apps/labrinth/src/database/models/collection_item.rs +++ b/apps/labrinth/src/database/models/collection_item.rs @@ -1,7 +1,7 @@ use super::ids::*; -use crate::database::models; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; +use crate::database::{PgTransaction, models}; use crate::models::collections::CollectionStatus; use chrono::{DateTime, Utc}; use dashmap::DashMap; @@ -23,7 +23,7 @@ pub struct CollectionBuilder { impl CollectionBuilder { pub async fn insert( self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let collection_struct = DBCollection { id: self.collection_id, @@ -61,7 +61,7 @@ pub struct DBCollection { impl DBCollection { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -83,7 +83,7 @@ impl DBCollection { self.raw_icon_url.as_ref(), self.status.to_string(), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let (collection_ids, project_ids): (Vec<_>, Vec<_>) = @@ -97,7 +97,7 @@ impl DBCollection { &collection_ids[..], &project_ids[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -105,10 +105,10 @@ impl DBCollection { pub async fn remove( id: DBCollectionId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { - let collection = Self::get(id, &mut **transaction, redis).await?; + let collection = Self::get(id, &mut *transaction, redis).await?; if let Some(collection) = collection { sqlx::query!( @@ -118,7 +118,7 @@ impl DBCollection { ", id as DBCollectionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -128,7 +128,7 @@ impl DBCollection { ", id as DBCollectionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; models::DBCollection::clear_cache(collection.id, redis).await?; @@ -145,7 +145,7 @@ impl DBCollection { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBCollection::get_many(&[id], executor, redis) .await @@ -158,7 +158,7 @@ impl DBCollection { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let val = redis .get_cached_keys( diff --git a/apps/labrinth/src/database/models/delphi_report_item.rs b/apps/labrinth/src/database/models/delphi_report_item.rs index 24b7ffc1c..f594b9bde 100644 --- a/apps/labrinth/src/database/models/delphi_report_item.rs +++ b/apps/labrinth/src/database/models/delphi_report_item.rs @@ -7,9 +7,12 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::types::Json; -use crate::database::models::{ - DBFileId, DBProjectId, DatabaseError, DelphiReportId, - DelphiReportIssueDetailsId, DelphiReportIssueId, +use crate::database::{ + PgTransaction, + models::{ + DBFileId, DBProjectId, DatabaseError, DelphiReportId, + DelphiReportIssueDetailsId, DelphiReportIssueId, + }, }; /// A Delphi malware analysis report for a project version file. @@ -32,7 +35,7 @@ pub struct DBDelphiReport { impl DBDelphiReport { pub async fn upsert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { Ok(DelphiReportId(sqlx::query_scalar!( " @@ -47,7 +50,7 @@ impl DBDelphiReport { self.artifact_url, self.severity as DelphiSeverity, ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await?)) } } @@ -181,7 +184,7 @@ pub struct DelphiReportIssueResult { impl DBDelphiReportIssue { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { Ok(DelphiReportIssueId( sqlx::query_scalar!( @@ -193,7 +196,7 @@ impl DBDelphiReportIssue { self.report_id as DelphiReportId, self.issue_type, ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await?, )) } @@ -234,7 +237,7 @@ pub struct ReportIssueDetail { impl ReportIssueDetail { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { Ok(DelphiReportIssueDetailsId(sqlx::query_scalar!( " @@ -249,19 +252,19 @@ impl ReportIssueDetail { sqlx::types::Json(&self.data) as Json<&HashMap>, self.severity as DelphiSeverity, ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await?)) } pub async fn remove_all_by_issue_id( issue_id: DelphiReportIssueId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { Ok(sqlx::query!( "DELETE FROM delphi_report_issue_details WHERE issue_id = $1", issue_id as DelphiReportIssueId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await? .rows_affected()) } diff --git a/apps/labrinth/src/database/models/friend_item.rs b/apps/labrinth/src/database/models/friend_item.rs index 1514057d1..272a3cf9b 100644 --- a/apps/labrinth/src/database/models/friend_item.rs +++ b/apps/labrinth/src/database/models/friend_item.rs @@ -1,4 +1,4 @@ -use crate::database::models::DBUserId; +use crate::database::{PgTransaction, models::DBUserId}; use chrono::{DateTime, Utc}; pub struct DBFriend { @@ -11,7 +11,7 @@ pub struct DBFriend { impl DBFriend { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -23,7 +23,7 @@ impl DBFriend { self.created, self.accepted, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -35,7 +35,7 @@ impl DBFriend { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let friend = sqlx::query!( " @@ -62,7 +62,7 @@ impl DBFriend { user_id: DBUserId, friend_id: DBUserId, accepted: bool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -74,7 +74,7 @@ impl DBFriend { friend_id.0, accepted, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -86,7 +86,7 @@ impl DBFriend { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let friends = sqlx::query!( " @@ -114,7 +114,7 @@ impl DBFriend { pub async fn remove( user_id: DBUserId, friend_id: DBUserId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -124,7 +124,7 @@ impl DBFriend { user_id.0 as i64, friend_id.0 as i64, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) diff --git a/apps/labrinth/src/database/models/ids.rs b/apps/labrinth/src/database/models/ids.rs index 10f8cc8ae..646d5e4cc 100644 --- a/apps/labrinth/src/database/models/ids.rs +++ b/apps/labrinth/src/database/models/ids.rs @@ -1,4 +1,5 @@ use super::DatabaseError; +use crate::database::PgTransaction; use crate::models::ids::{ AffiliateCodeId, ChargeId, CollectionId, FileId, ImageId, NotificationId, OAuthAccessTokenId, OAuthClientAuthorizationId, OAuthClientId, @@ -21,7 +22,7 @@ const ID_RETRY_COUNT: usize = 20; macro_rules! generate_ids { ($function_name:ident, $return_type:ident, $select_stmnt:expr) => { pub async fn $function_name( - con: &mut sqlx::Transaction<'_, sqlx::Postgres>, + con: &mut PgTransaction<'_>, ) -> Result<$return_type, DatabaseError> { let mut rng = ChaCha20Rng::from_entropy(); let length = 8; @@ -32,7 +33,7 @@ macro_rules! generate_ids { // Check if ID is unique loop { let results = sqlx::query!($select_stmnt, id as i64) - .fetch_one(&mut **con) + .fetch_one(&mut *con) .await?; if results.exists.unwrap_or(true) @@ -58,7 +59,7 @@ macro_rules! generate_bulk_ids { ($function_name:ident, $return_type:ident, $select_stmnt:expr) => { pub async fn $function_name( count: usize, - con: &mut sqlx::Transaction<'_, sqlx::Postgres>, + con: &mut PgTransaction<'_>, ) -> Result, DatabaseError> { let mut retry_count = 0; @@ -73,7 +74,7 @@ macro_rules! generate_bulk_ids { (0..count).map(|x| base + x as i64).collect::>(); let results = sqlx::query!($select_stmnt, &ids) - .fetch_one(&mut **con) + .fetch_one(&mut *con) .await?; if !results.exists.unwrap_or(true) { diff --git a/apps/labrinth/src/database/models/image_item.rs b/apps/labrinth/src/database/models/image_item.rs index d85c0a2d5..a65736dcf 100644 --- a/apps/labrinth/src/database/models/image_item.rs +++ b/apps/labrinth/src/database/models/image_item.rs @@ -1,4 +1,5 @@ use super::ids::*; +use crate::database::PgTransaction; use crate::database::redis::RedisPool; use crate::{database::models::DatabaseError, models::images::ImageContext}; use chrono::{DateTime, Utc}; @@ -28,7 +29,7 @@ pub struct DBImage { impl DBImage { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -51,7 +52,7 @@ impl DBImage { self.thread_message_id.map(|x| x.0), self.report_id.map(|x| x.0), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -59,10 +60,10 @@ impl DBImage { pub async fn remove( id: DBImageId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { - let image = Self::get(id, &mut **transaction, redis).await?; + let image = Self::get(id, &mut *transaction, redis).await?; if let Some(image) = image { sqlx::query!( @@ -72,7 +73,7 @@ impl DBImage { ", id as DBImageId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; DBImage::clear_cache(image.id, redis).await?; @@ -85,7 +86,7 @@ impl DBImage { pub async fn get_many_contexted( context: ImageContext, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::Error> { // Set all of project_id, version_id, thread_message_id, report_id to None // Then set the one that is relevant to Some @@ -137,7 +138,7 @@ impl DBImage { report_id.map(|x| x.0), ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|row| { let id = DBImageId(row.id); @@ -165,7 +166,7 @@ impl DBImage { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBImage::get_many(&[id], executor, redis) .await @@ -178,7 +179,7 @@ impl DBImage { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::TryStreamExt; diff --git a/apps/labrinth/src/database/models/legacy_loader_fields.rs b/apps/labrinth/src/database/models/legacy_loader_fields.rs index b2f8a5b2c..84e012f0a 100644 --- a/apps/labrinth/src/database/models/legacy_loader_fields.rs +++ b/apps/labrinth/src/database/models/legacy_loader_fields.rs @@ -43,11 +43,11 @@ impl MinecraftGameVersion { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { let mut exec = exec.acquire().await?; let game_version_enum = - LoaderFieldEnum::get(Self::FIELD_NAME, &mut *exec, redis) + LoaderFieldEnum::get(Self::FIELD_NAME, &mut exec, redis) .await? .ok_or_else(|| { DatabaseError::SchemaError( @@ -55,7 +55,7 @@ impl MinecraftGameVersion { ) })?; let game_version_enum_values = - LoaderFieldEnumValue::list(game_version_enum.id, &mut *exec, redis) + LoaderFieldEnumValue::list(game_version_enum.id, &mut exec, redis) .await?; let game_versions = game_version_enum_values @@ -180,7 +180,7 @@ impl<'a> MinecraftGameVersionBuilder<'a> { redis: &RedisPool, ) -> Result where - E: sqlx::Executor<'b, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'b, Database = sqlx::Postgres> + Copy, { let game_versions_enum = LoaderFieldEnum::get("game_versions", exec, redis) @@ -205,7 +205,7 @@ impl<'a> MinecraftGameVersionBuilder<'a> { ON CONFLICT (enum_id, value) DO UPDATE SET metadata = jsonb_set( COALESCE(loader_field_enum_values.metadata, $4), - '{type}', + '{type}', COALESCE($4->'type', loader_field_enum_values.metadata->'type') ), created = COALESCE($3, loader_field_enum_values.created) diff --git a/apps/labrinth/src/database/models/loader_fields.rs b/apps/labrinth/src/database/models/loader_fields.rs index db84cb757..e47735910 100644 --- a/apps/labrinth/src/database/models/loader_fields.rs +++ b/apps/labrinth/src/database/models/loader_fields.rs @@ -3,6 +3,7 @@ use std::hash::Hasher; use super::DatabaseError; use super::ids::*; +use crate::database::PgTransaction; use crate::database::redis::RedisPool; use chrono::DateTime; use chrono::Utc; @@ -35,7 +36,7 @@ impl Game { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Ok(Self::list(exec, redis) .await? @@ -48,7 +49,7 @@ impl Game { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -108,7 +109,7 @@ impl Loader { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -145,7 +146,7 @@ impl Loader { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -379,7 +380,7 @@ impl LoaderField { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let fields = Self::get_fields(loader_ids, exec, redis).await?; Ok(fields.into_iter().find(|f| f.field == field)) @@ -393,7 +394,7 @@ impl LoaderField { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let found_loader_fields = Self::get_fields_per_loader(loader_ids, exec, redis).await?; @@ -411,7 +412,7 @@ impl LoaderField { redis: &RedisPool, ) -> Result>, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let val = redis.get_cached_keys_raw( LOADER_FIELDS_NAMESPACE, @@ -464,7 +465,7 @@ impl LoaderField { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -523,7 +524,7 @@ impl LoaderFieldEnum { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -579,7 +580,7 @@ impl LoaderFieldEnumValue { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Ok(Self::list_many(&[loader_field_enum_id], exec, redis) .await? @@ -595,7 +596,7 @@ impl LoaderFieldEnumValue { redis: &RedisPool, ) -> Result>, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let get_enum_id = |x: &LoaderField| match x.field_type { LoaderFieldType::Enum(id) | LoaderFieldType::ArrayEnum(id) => { @@ -634,7 +635,7 @@ impl LoaderFieldEnumValue { DatabaseError, > where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let val = redis.get_cached_keys_raw( LOADER_FIELD_ENUM_VALUES_NAMESPACE, @@ -687,7 +688,7 @@ impl LoaderFieldEnumValue { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = Self::list(loader_field_enum_id, exec, redis) .await? @@ -712,7 +713,7 @@ impl LoaderFieldEnumValue { impl VersionField { pub async fn insert_many( items: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let mut query_version_fields = vec![]; for item in items { @@ -792,7 +793,7 @@ impl VersionField { &string_values[..] as &[Option], &enum_values[..] as &[i32] ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) diff --git a/apps/labrinth/src/database/models/moderation_lock_item.rs b/apps/labrinth/src/database/models/moderation_lock_item.rs index 45634d745..f9dbb6558 100644 --- a/apps/labrinth/src/database/models/moderation_lock_item.rs +++ b/apps/labrinth/src/database/models/moderation_lock_item.rs @@ -1,6 +1,6 @@ +use crate::database::PgPool; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use crate::database::models::{DBProjectId, DBUserId}; diff --git a/apps/labrinth/src/database/models/notification_item.rs b/apps/labrinth/src/database/models/notification_item.rs index f3cedf477..ae0107633 100644 --- a/apps/labrinth/src/database/models/notification_item.rs +++ b/apps/labrinth/src/database/models/notification_item.rs @@ -1,4 +1,5 @@ use super::ids::*; +use crate::database::PgTransaction; use crate::database::{models::DatabaseError, redis::RedisPool}; use crate::models::notifications::{ NotificationBody, NotificationChannel, NotificationDeliveryStatus, @@ -36,7 +37,7 @@ impl NotificationBuilder { pub async fn insert( &self, user: DBUserId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result<(), DatabaseError> { self.insert_many(vec![user], transaction, redis).await @@ -45,7 +46,7 @@ impl NotificationBuilder { pub async fn insert_many_payout_notifications( users: Vec, dates_available: Vec>, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result<(), DatabaseError> { let notification_ids = @@ -87,7 +88,7 @@ impl NotificationBuilder { &users_raw_ids[..], &dates_available[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let notification_types = notification_ids @@ -111,7 +112,7 @@ impl NotificationBuilder { pub async fn insert_many( &self, users: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result<(), DatabaseError> { let notification_ids = @@ -139,7 +140,7 @@ impl NotificationBuilder { &users_raw_ids[..], &bodies[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let notification_types = notification_ids @@ -161,7 +162,7 @@ impl NotificationBuilder { } pub async fn insert_many_deliveries( - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, notification_ids: &[i64], users_raw_ids: &[i64], @@ -245,7 +246,7 @@ impl NotificationBuilder { NotificationDeliveryStatus::SkippedDefault.as_str(), ); - query.execute(&mut **transaction).await?; + query.execute(&mut *transaction).await?; DBNotification::clear_user_notifications_cache(users, redis).await?; @@ -259,7 +260,7 @@ impl DBNotification { executor: E, ) -> Result, sqlx::error::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { Self::get_many(&[id], executor) .await @@ -271,7 +272,7 @@ impl DBNotification { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let notification_ids_parsed: Vec = notification_ids.iter().map(|x| x.0).collect(); @@ -324,7 +325,7 @@ impl DBNotification { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let db_notifications = sqlx::query!( " @@ -378,7 +379,7 @@ impl DBNotification { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { { let mut redis = redis.connect().await?; @@ -455,7 +456,7 @@ impl DBNotification { pub async fn read( id: DBNotificationId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { Self::read_many(&[id], transaction, redis).await @@ -463,7 +464,7 @@ impl DBNotification { pub async fn read_many( notification_ids: &[DBNotificationId], - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { let notification_ids_parsed: Vec = @@ -478,7 +479,7 @@ impl DBNotification { ", ¬ification_ids_parsed ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|x| DBUserId(x.user_id)) .try_collect::>() .await?; @@ -494,7 +495,7 @@ impl DBNotification { pub async fn remove( id: DBNotificationId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { Self::remove_many(&[id], transaction, redis).await @@ -502,7 +503,7 @@ impl DBNotification { pub async fn remove_many( notification_ids: &[DBNotificationId], - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { let notification_ids_parsed: Vec = @@ -515,7 +516,7 @@ impl DBNotification { ", ¬ification_ids_parsed ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -525,7 +526,7 @@ impl DBNotification { ", ¬ification_ids_parsed ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let affected_users = sqlx::query!( @@ -536,7 +537,7 @@ impl DBNotification { ", ¬ification_ids_parsed ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|x| DBUserId(x.user_id)) .try_collect::>() .await?; diff --git a/apps/labrinth/src/database/models/notifications_deliveries_item.rs b/apps/labrinth/src/database/models/notifications_deliveries_item.rs index 28b672954..616f70736 100644 --- a/apps/labrinth/src/database/models/notifications_deliveries_item.rs +++ b/apps/labrinth/src/database/models/notifications_deliveries_item.rs @@ -60,7 +60,7 @@ impl From for DBNotificationDelivery { impl DBNotificationDelivery { pub async fn get_all_user( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let user_id = user_id.0; let results = select_notification_deliveries_with_predicate!( @@ -78,7 +78,7 @@ impl DBNotificationDelivery { pub async fn lock_channel_processable( channel: NotificationChannel, limit: i64, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { // This follows the `idx_notifications_deliveries_composite_queue` index. Ok(select_notification_deliveries_with_predicate!( @@ -107,7 +107,7 @@ impl DBNotificationDelivery { /// Inserts the row into the table and updates its ID. pub async fn insert( &mut self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { let id = sqlx::query_scalar!( " @@ -136,7 +136,7 @@ impl DBNotificationDelivery { /// Updates semantically mutable columns of the row. pub async fn update( &self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { sqlx::query!( " diff --git a/apps/labrinth/src/database/models/notifications_template_item.rs b/apps/labrinth/src/database/models/notifications_template_item.rs index 4dafb395c..607e0d60d 100644 --- a/apps/labrinth/src/database/models/notifications_template_item.rs +++ b/apps/labrinth/src/database/models/notifications_template_item.rs @@ -49,7 +49,7 @@ impl From for NotificationTemplate { impl NotificationTemplate { pub async fn list_channel( channel: NotificationChannel, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, redis: &RedisPool, ) -> Result, DatabaseError> { { diff --git a/apps/labrinth/src/database/models/notifications_type_item.rs b/apps/labrinth/src/database/models/notifications_type_item.rs index 44528e796..0179dbf7d 100644 --- a/apps/labrinth/src/database/models/notifications_type_item.rs +++ b/apps/labrinth/src/database/models/notifications_type_item.rs @@ -37,7 +37,7 @@ impl NotificationTypeItem { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; diff --git a/apps/labrinth/src/database/models/oauth_client_authorization_item.rs b/apps/labrinth/src/database/models/oauth_client_authorization_item.rs index cc47344f3..64a4bf989 100644 --- a/apps/labrinth/src/database/models/oauth_client_authorization_item.rs +++ b/apps/labrinth/src/database/models/oauth_client_authorization_item.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use crate::models::pats::Scopes; +use crate::{database::PgTransaction, models::pats::Scopes}; use super::{ DBOAuthClientAuthorizationId, DBOAuthClientId, DBUserId, DatabaseError, @@ -41,7 +41,7 @@ impl DBOAuthClientAuthorization { pub async fn get( client_id: DBOAuthClientId, user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let value = sqlx::query_as!( DBAuthClientAuthorizationQueryResult, @@ -61,7 +61,7 @@ impl DBOAuthClientAuthorization { pub async fn get_all_for_user( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let results = sqlx::query_as!( DBAuthClientAuthorizationQueryResult, @@ -83,7 +83,7 @@ impl DBOAuthClientAuthorization { client_id: DBOAuthClientId, user_id: DBUserId, scopes: Scopes, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -101,7 +101,7 @@ impl DBOAuthClientAuthorization { user_id.0, scopes.bits() as i64, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -110,7 +110,7 @@ impl DBOAuthClientAuthorization { pub async fn remove( client_id: DBOAuthClientId, user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { sqlx::query!( " diff --git a/apps/labrinth/src/database/models/oauth_client_item.rs b/apps/labrinth/src/database/models/oauth_client_item.rs index faaeb5eef..a677a254e 100644 --- a/apps/labrinth/src/database/models/oauth_client_item.rs +++ b/apps/labrinth/src/database/models/oauth_client_item.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use sha2::Digest; use super::{DBOAuthClientId, DBOAuthRedirectUriId, DBUserId, DatabaseError}; -use crate::models::pats::Scopes; +use crate::{database::PgTransaction, models::pats::Scopes}; #[derive(Deserialize, Serialize, Clone, Debug)] pub struct DBOAuthRedirectUri { @@ -80,14 +80,14 @@ macro_rules! select_clients_with_predicate { impl DBOAuthClient { pub async fn get( id: DBOAuthClientId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { Ok(Self::get_many(&[id], exec).await?.into_iter().next()) } pub async fn get_many( ids: &[DBOAuthClientId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let ids = ids.iter().map(|id| id.0).collect_vec(); let ids_ref: &[i64] = &ids; @@ -103,7 +103,7 @@ impl DBOAuthClient { pub async fn get_all_user_clients( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let user_id_param = user_id.0; let clients = select_clients_with_predicate!( @@ -118,7 +118,7 @@ impl DBOAuthClient { pub async fn remove( id: DBOAuthClientId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { // Cascades to oauth_client_redirect_uris, oauth_client_authorizations sqlx::query!( @@ -136,7 +136,7 @@ impl DBOAuthClient { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -155,10 +155,10 @@ impl DBOAuthClient { self.secret_hash, self.created_by.0 ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; - Self::insert_redirect_uris(&self.redirect_uris, &mut **transaction) + Self::insert_redirect_uris(&self.redirect_uris, &mut *transaction) .await?; Ok(()) @@ -166,7 +166,7 @@ impl DBOAuthClient { pub async fn update_editable_fields( &self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -190,7 +190,7 @@ impl DBOAuthClient { pub async fn remove_redirect_uris( ids: impl IntoIterator, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { let ids = ids.into_iter().map(|id| id.0).collect_vec(); sqlx::query!( @@ -209,7 +209,7 @@ impl DBOAuthClient { pub async fn insert_redirect_uris( uris: &[DBOAuthRedirectUri], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { let (ids, client_ids, uris): (Vec<_>, Vec<_>, Vec<_>) = uris .iter() diff --git a/apps/labrinth/src/database/models/oauth_token_item.rs b/apps/labrinth/src/database/models/oauth_token_item.rs index 2196cc8a3..b4191bff0 100644 --- a/apps/labrinth/src/database/models/oauth_token_item.rs +++ b/apps/labrinth/src/database/models/oauth_token_item.rs @@ -25,7 +25,7 @@ pub struct DBOAuthAccessToken { impl DBOAuthAccessToken { pub async fn get( token_hash: String, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let value = sqlx::query!( " @@ -65,7 +65,7 @@ impl DBOAuthAccessToken { /// Inserts and returns the time until the token expires pub async fn insert( &self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result { let r = sqlx::query!( " diff --git a/apps/labrinth/src/database/models/organization_item.rs b/apps/labrinth/src/database/models/organization_item.rs index 56637d01f..bdef0009b 100644 --- a/apps/labrinth/src/database/models/organization_item.rs +++ b/apps/labrinth/src/database/models/organization_item.rs @@ -1,3 +1,4 @@ +use crate::database::PgTransaction; use crate::database::redis::RedisPool; use ariadne::ids::base62_impl::parse_base62; use dashmap::DashMap; @@ -38,7 +39,7 @@ pub struct DBOrganization { impl DBOrganization { pub async fn insert( self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), super::DatabaseError> { sqlx::query!( " @@ -54,7 +55,7 @@ impl DBOrganization { self.raw_icon_url, self.color.map(|x| x as i32), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -66,7 +67,7 @@ impl DBOrganization { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many(&[string], exec, redis) .await @@ -79,7 +80,7 @@ impl DBOrganization { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many_ids(&[id], exec, redis) .await @@ -92,7 +93,7 @@ impl DBOrganization { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let ids = organization_ids .iter() @@ -111,7 +112,7 @@ impl DBOrganization { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let val = redis .get_cached_keys_with_slug( @@ -172,7 +173,7 @@ impl DBOrganization { exec: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -205,10 +206,10 @@ impl DBOrganization { pub async fn remove( id: DBOrganizationId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, super::DatabaseError> { - let organization = Self::get_id(id, &mut **transaction, redis).await?; + let organization = Self::get_id(id, &mut *transaction, redis).await?; if let Some(organization) = organization { sqlx::query!( @@ -218,7 +219,7 @@ impl DBOrganization { ", id as DBOrganizationId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; DBTeamMember::clear_cache(organization.team_id, redis).await?; @@ -230,7 +231,7 @@ impl DBOrganization { ", organization.team_id as DBTeamId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -240,7 +241,7 @@ impl DBOrganization { ", organization.team_id as DBTeamId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/pat_item.rs b/apps/labrinth/src/database/models/pat_item.rs index 735f7efd7..9a9992f5d 100644 --- a/apps/labrinth/src/database/models/pat_item.rs +++ b/apps/labrinth/src/database/models/pat_item.rs @@ -1,4 +1,5 @@ use super::ids::*; +use crate::database::PgTransaction; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; use crate::models::pats::Scopes; @@ -29,7 +30,7 @@ pub struct DBPersonalAccessToken { impl DBPersonalAccessToken { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -49,7 +50,7 @@ impl DBPersonalAccessToken { self.user_id as DBUserId, self.expires ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -65,7 +66,7 @@ impl DBPersonalAccessToken { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many(&[id], exec, redis) .await @@ -78,7 +79,7 @@ impl DBPersonalAccessToken { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let ids = pat_ids .iter() @@ -97,7 +98,7 @@ impl DBPersonalAccessToken { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let val = redis .get_cached_keys_with_slug( @@ -154,7 +155,7 @@ impl DBPersonalAccessToken { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -228,7 +229,7 @@ impl DBPersonalAccessToken { pub async fn remove( id: DBPatId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::error::Error> { sqlx::query!( " @@ -236,7 +237,7 @@ impl DBPersonalAccessToken { ", id as DBPatId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/payout_item.rs b/apps/labrinth/src/database/models/payout_item.rs index 102f4f4d2..df9d5816e 100644 --- a/apps/labrinth/src/database/models/payout_item.rs +++ b/apps/labrinth/src/database/models/payout_item.rs @@ -1,4 +1,7 @@ -use crate::models::payouts::{PayoutMethodType, PayoutStatus}; +use crate::{ + database::PgTransaction, + models::payouts::{PayoutMethodType, PayoutStatus}, +}; use chrono::{DateTime, Utc}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; @@ -26,7 +29,7 @@ pub struct DBPayout { impl DBPayout { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -47,7 +50,7 @@ impl DBPayout { self.method_address, self.platform_id, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -58,7 +61,7 @@ impl DBPayout { executor: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBPayout::get_many(&[id], executor) .await @@ -70,7 +73,7 @@ impl DBPayout { exec: E, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::TryStreamExt; @@ -103,7 +106,7 @@ impl DBPayout { pub async fn get_all_for_user( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let results = sqlx::query!( " diff --git a/apps/labrinth/src/database/models/product_item.rs b/apps/labrinth/src/database/models/product_item.rs index e3c8a620e..e7d48f810 100644 --- a/apps/labrinth/src/database/models/product_item.rs +++ b/apps/labrinth/src/database/models/product_item.rs @@ -55,14 +55,14 @@ impl TryFrom for DBProduct { impl DBProduct { pub async fn get( id: DBProductId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { Ok(Self::get_many(&[id], exec).await?.into_iter().next()) } pub async fn get_price( id: DBProductPriceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let maybe_row = select_products_with_predicate!( "INNER JOIN products_prices pp ON pp.id = $1 @@ -99,7 +99,7 @@ impl DBProduct { pub async fn get_many( ids: &[DBProductId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let ids = ids.iter().map(|id| id.0).collect_vec(); let ids_ref: &[i64] = &ids; @@ -117,7 +117,7 @@ impl DBProduct { } pub async fn get_all( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let one = 1; let results = select_products_with_predicate!("WHERE 1 = $1", one) @@ -148,7 +148,7 @@ impl QueryProductWithPrices { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { { let mut redis = redis.connect().await?; @@ -292,14 +292,14 @@ impl TryFrom for DBProductPrice { impl DBProductPrice { pub async fn get( id: DBProductPriceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { Ok(Self::get_many(&[id], exec).await?.into_iter().next()) } pub async fn get_many( ids: &[DBProductPriceId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let ids = ids.iter().map(|id| id.0).collect_vec(); let ids_ref: &[i64] = &ids; @@ -318,7 +318,7 @@ impl DBProductPrice { pub async fn get_all_product_prices( product_id: DBProductId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let res = Self::get_all_products_prices(&[product_id], exec).await?; @@ -327,7 +327,7 @@ impl DBProductPrice { pub async fn get_all_public_product_prices( product_id: DBProductId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let res = Self::get_all_public_products_prices(&[product_id], exec).await?; @@ -339,7 +339,7 @@ impl DBProductPrice { /// it won't be included in the resulting map. pub async fn get_all_public_products_prices( product_ids: &[DBProductId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result>, DatabaseError> { Self::get_all_products_prices_with_visibility( product_ids, @@ -351,7 +351,7 @@ impl DBProductPrice { pub async fn get_all_products_prices( product_ids: &[DBProductId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result>, DatabaseError> { Self::get_all_products_prices_with_visibility(product_ids, None, exec) .await @@ -360,7 +360,7 @@ impl DBProductPrice { async fn get_all_products_prices_with_visibility( product_ids: &[DBProductId], public_filter: Option, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result>, DatabaseError> { let ids = product_ids.iter().map(|id| id.0).collect_vec(); let ids_ref: &[i64] = &ids; diff --git a/apps/labrinth/src/database/models/products_tax_identifier_item.rs b/apps/labrinth/src/database/models/products_tax_identifier_item.rs index d95ea814f..506a82ce2 100644 --- a/apps/labrinth/src/database/models/products_tax_identifier_item.rs +++ b/apps/labrinth/src/database/models/products_tax_identifier_item.rs @@ -11,7 +11,7 @@ pub struct DBProductsTaxIdentifier { impl DBProductsTaxIdentifier { pub async fn get_product( product_id: DBProductId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, ApiError> { let maybe_row = sqlx::query!( "SELECT * FROM products_tax_identifiers WHERE product_id = $1", @@ -29,7 +29,7 @@ impl DBProductsTaxIdentifier { pub async fn get_price( price_id: DBProductPriceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, ApiError> { let maybe_row = sqlx::query!( " @@ -58,7 +58,7 @@ pub struct ProductInfo { pub async fn product_info_by_product_price_id( product_price_id: DBProductPriceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, ApiError> { let maybe_row = sqlx::query!( r#" diff --git a/apps/labrinth/src/database/models/project_item.rs b/apps/labrinth/src/database/models/project_item.rs index 717ebf7e4..b4db9530f 100644 --- a/apps/labrinth/src/database/models/project_item.rs +++ b/apps/labrinth/src/database/models/project_item.rs @@ -3,9 +3,9 @@ use super::loader_fields::{ VersionField, }; use super::{DBUser, ids::*}; -use crate::database::models; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; +use crate::database::{PgTransaction, models}; use crate::models::projects::{ MonetizationStatus, ProjectStatus, SideTypesMigrationReviewStatus, }; @@ -34,7 +34,7 @@ impl LinkUrl { pub async fn insert_many_projects( links: Vec, project_id: DBProjectId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { let (project_ids, platform_ids, urls): (Vec<_>, Vec<_>, Vec<_>) = links .into_iter() @@ -51,7 +51,7 @@ impl LinkUrl { &platform_ids[..], &urls[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -73,7 +73,7 @@ impl DBGalleryItem { pub async fn insert_many( items: Vec, project_id: DBProjectId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { let ( project_ids, @@ -112,7 +112,7 @@ impl DBGalleryItem { &descriptions[..] as &[Option], &orderings[..] ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -128,7 +128,7 @@ pub struct DBModCategory { impl DBModCategory { pub async fn insert_many( items: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let (project_ids, category_ids, is_additionals): ( Vec<_>, @@ -147,7 +147,7 @@ impl DBModCategory { &category_ids[..], &is_additionals[..] ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -181,7 +181,7 @@ pub struct ProjectBuilder { impl ProjectBuilder { pub async fn insert( self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let project_struct = DBProject { id: self.project_id, @@ -299,7 +299,7 @@ pub struct DBProject { impl DBProject { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -337,7 +337,7 @@ impl DBProject { self.organization_id.map(|x| x.0 as i64), self.side_types_migration_review_status.as_str() ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -345,10 +345,10 @@ impl DBProject { pub async fn remove( id: DBProjectId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { - let project = Self::get_id(id, &mut **transaction, redis).await?; + let project = Self::get_id(id, &mut *transaction, redis).await?; if let Some(project) = project { DBProject::clear_cache(id, project.inner.slug, Some(true), redis) @@ -361,7 +361,7 @@ impl DBProject { ", id as DBProjectId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -371,7 +371,7 @@ impl DBProject { ", id as DBProjectId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -381,7 +381,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -392,7 +392,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -402,7 +402,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -412,7 +412,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; for version in project.versions { @@ -426,7 +426,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -437,7 +437,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -447,7 +447,7 @@ impl DBProject { ", id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; models::DBTeamMember::clear_cache(project.inner.team_id, redis) @@ -461,7 +461,7 @@ impl DBProject { ", project.inner.team_id as DBTeamId, ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|x| DBUserId(x.user_id)) .try_collect::>() .await?; @@ -475,7 +475,7 @@ impl DBProject { ", project.inner.team_id as DBTeamId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) @@ -490,7 +490,7 @@ impl DBProject { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { DBProject::get_many(&[string], executor, redis) .await @@ -503,7 +503,7 @@ impl DBProject { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { DBProject::get_many( &[crate::models::ids::ProjectId::from(id)], @@ -520,7 +520,7 @@ impl DBProject { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { let ids = project_ids .iter() @@ -539,7 +539,7 @@ impl DBProject { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { let val = redis.get_cached_keys_with_slug( PROJECTS_NAMESPACE, @@ -573,7 +573,7 @@ impl DBProject { .map(|x| x.to_string()) .collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold( DashMap::new(), |acc: DashMap)>>, m| { @@ -598,7 +598,7 @@ impl DBProject { ", &all_version_ids.iter().map(|x| x.0).collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold( DashMap::new(), |acc: DashMap>, m| { @@ -632,7 +632,7 @@ impl DBProject { .map(|x| x.0) .collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .map_ok(|m| QueryLoaderFieldEnumValue { id: LoaderFieldEnumValueId(m.id), enum_id: LoaderFieldEnumId(m.enum_id), @@ -653,7 +653,7 @@ impl DBProject { ", &project_ids_parsed, &slugs - ).fetch(&mut *exec) + ).fetch(&mut exec) .try_fold(DashMap::new(), |acc : DashMap>, m| { acc.entry(DBProjectId(m.mod_id)) .or_default() @@ -680,7 +680,7 @@ impl DBProject { ", &project_ids_parsed, &slugs - ).fetch(&mut *exec) + ).fetch(&mut exec) .try_fold(DashMap::new(), |acc : DashMap>, m| { acc.entry(DBProjectId(m.mod_id)) .or_default() @@ -722,7 +722,7 @@ impl DBProject { GROUP BY mod_id ", &all_version_ids.iter().map(|x| x.0).collect::>() - ).fetch(&mut *exec) + ).fetch(&mut exec) .map_ok(|m| { let project_id = DBProjectId(m.mod_id); @@ -753,7 +753,7 @@ impl DBProject { ", &loader_field_ids.iter().map(|x| x.0).collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .map_ok(|m| QueryLoaderField { id: LoaderFieldId(m.id), field: m.field, @@ -788,7 +788,7 @@ impl DBProject { &project_ids_parsed, &slugs, ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold(DashMap::new(), |acc, m| { let id = m.id; let project_id = DBProjectId(id); @@ -885,7 +885,7 @@ impl DBProject { DatabaseError, > where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { type Dependencies = Vec<( Option, diff --git a/apps/labrinth/src/database/models/report_item.rs b/apps/labrinth/src/database/models/report_item.rs index 2d105da4f..506510b05 100644 --- a/apps/labrinth/src/database/models/report_item.rs +++ b/apps/labrinth/src/database/models/report_item.rs @@ -1,3 +1,5 @@ +use crate::database::PgTransaction; + use super::ids::*; use chrono::{DateTime, Utc}; @@ -29,7 +31,7 @@ pub struct ReportQueryResult { impl DBReport { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { sqlx::query!( " @@ -50,7 +52,7 @@ impl DBReport { self.body, self.reporter as DBUserId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -61,7 +63,7 @@ impl DBReport { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many(&[id], exec) .await @@ -73,7 +75,7 @@ impl DBReport { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -111,7 +113,7 @@ impl DBReport { pub async fn remove_full( id: DBReportId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::error::Error> { let result = sqlx::query!( " @@ -119,7 +121,7 @@ impl DBReport { ", id as DBReportId ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await?; if !result.exists.unwrap_or(false) { @@ -133,7 +135,7 @@ impl DBReport { ", id as DBReportId ) - .fetch_optional(&mut **transaction) + .fetch_optional(&mut *transaction) .await?; if let Some(thread_id) = thread_id { @@ -150,7 +152,7 @@ impl DBReport { ", id as DBReportId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/session_item.rs b/apps/labrinth/src/database/models/session_item.rs index 2b1bac1cb..e835bb15c 100644 --- a/apps/labrinth/src/database/models/session_item.rs +++ b/apps/labrinth/src/database/models/session_item.rs @@ -1,4 +1,5 @@ use super::ids::*; +use crate::database::PgTransaction; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; use ariadne::ids::base62_impl::parse_base62; @@ -29,7 +30,7 @@ pub struct SessionBuilder { impl SessionBuilder { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let id = generate_session_id(transaction).await?; @@ -54,7 +55,7 @@ impl SessionBuilder { self.ip, self.user_agent, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(id) @@ -92,7 +93,7 @@ impl DBSession { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many(&[id], exec, redis) .await @@ -105,7 +106,7 @@ impl DBSession { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBSession::get_many( &[crate::models::ids::SessionId::from(id)], @@ -122,7 +123,7 @@ impl DBSession { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let ids = session_ids .iter() @@ -141,7 +142,7 @@ impl DBSession { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::TryStreamExt; @@ -207,7 +208,7 @@ impl DBSession { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { { let mut redis = redis.connect().await?; @@ -286,7 +287,7 @@ impl DBSession { pub async fn remove( id: DBSessionId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::error::Error> { sqlx::query!( " @@ -294,7 +295,7 @@ impl DBSession { ", id as DBSessionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/shared_instance_item.rs b/apps/labrinth/src/database/models/shared_instance_item.rs index 2be240850..896297fbe 100644 --- a/apps/labrinth/src/database/models/shared_instance_item.rs +++ b/apps/labrinth/src/database/models/shared_instance_item.rs @@ -1,3 +1,4 @@ +use crate::database::PgTransaction; use crate::database::models::{ DBSharedInstanceId, DBSharedInstanceVersionId, DBUserId, }; @@ -42,7 +43,7 @@ impl From for DBSharedInstance { impl DBSharedInstance { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -54,7 +55,7 @@ impl DBSharedInstance { self.owner_id as DBUserId, self.current_version_id.map(|x| x.0), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -62,7 +63,7 @@ impl DBSharedInstance { pub async fn get( id: DBSharedInstanceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, sqlx::Error> { let result = sqlx::query_as!( SharedInstanceQueryResult, @@ -81,7 +82,7 @@ impl DBSharedInstance { pub async fn list_for_user( user: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, sqlx::Error> { let results = sqlx::query_as!( SharedInstanceQueryResult, @@ -129,7 +130,7 @@ pub struct DBSharedInstanceUser { impl DBSharedInstanceUser { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -140,7 +141,7 @@ impl DBSharedInstanceUser { self.shared_instance_id as DBSharedInstanceId, self.permissions.bits() as i64, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -149,7 +150,7 @@ impl DBSharedInstanceUser { pub async fn get_user_permissions( instance_id: DBSharedInstanceId, user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, super::DatabaseError> { let permissions = sqlx::query!( @@ -173,7 +174,7 @@ impl DBSharedInstanceUser { pub async fn get_from_instance( instance_id: DBSharedInstanceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, redis: &RedisPool, ) -> Result, super::DatabaseError> { Self::get_from_instance_many(&[instance_id], exec, redis).await @@ -181,7 +182,7 @@ impl DBSharedInstanceUser { pub async fn get_from_instance_many( instance_ids: &[DBSharedInstanceId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, redis: &RedisPool, ) -> Result, super::DatabaseError> { if instance_ids.is_empty() { @@ -274,7 +275,7 @@ impl From for DBSharedInstanceVersion { impl DBSharedInstanceVersion { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::Error> { sqlx::query!( " @@ -287,7 +288,7 @@ impl DBSharedInstanceVersion { self.sha512, self.created, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -295,7 +296,7 @@ impl DBSharedInstanceVersion { pub async fn get( id: DBSharedInstanceVersionId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, sqlx::Error> { let result = sqlx::query_as!( SharedInstanceVersionQueryResult, @@ -314,7 +315,7 @@ impl DBSharedInstanceVersion { pub async fn get_for_instance( instance_id: DBSharedInstanceId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, sqlx::Error> { let results = sqlx::query_as!( SharedInstanceVersionQueryResult, diff --git a/apps/labrinth/src/database/models/team_item.rs b/apps/labrinth/src/database/models/team_item.rs index dc3139401..12cb44c02 100644 --- a/apps/labrinth/src/database/models/team_item.rs +++ b/apps/labrinth/src/database/models/team_item.rs @@ -1,6 +1,6 @@ use super::{DBOrganization, DBProject, ids::*}; use crate::{ - database::redis::RedisPool, + database::{PgTransaction, redis::RedisPool}, models::teams::{OrganizationPermissions, ProjectPermissions}, }; use dashmap::DashMap; @@ -28,7 +28,7 @@ pub struct TeamMemberBuilder { impl TeamBuilder { pub async fn insert( self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let team_id = generate_team_id(transaction).await?; @@ -41,7 +41,7 @@ impl TeamBuilder { ", team.id as DBTeamId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let mut team_member_ids = Vec::new(); @@ -101,7 +101,7 @@ impl TeamBuilder { &payouts_splits[..], &orderings[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(team_id) @@ -126,7 +126,7 @@ impl DBTeam { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -195,7 +195,7 @@ impl DBTeamMember { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { Self::get_from_team_full_many(&[id], executor, redis).await } @@ -206,7 +206,7 @@ impl DBTeamMember { redis: &RedisPool, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { if team_ids.is_empty() { return Ok(Vec::new()); @@ -276,7 +276,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_from_user_id_many(&[id], user_id, executor) .await @@ -290,7 +290,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let team_ids_parsed: Vec = team_ids.iter().map(|x| x.0).collect(); @@ -335,7 +335,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -379,7 +379,7 @@ impl DBTeamMember { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { sqlx::query!( " @@ -400,7 +400,7 @@ impl DBTeamMember { self.accepted, self.payouts_split ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -409,7 +409,7 @@ impl DBTeamMember { pub async fn delete( id: DBTeamId, user_id: DBUserId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), super::DatabaseError> { sqlx::query!( " @@ -419,7 +419,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -436,7 +436,7 @@ impl DBTeamMember { new_payouts_split: Option, new_ordering: Option, new_is_owner: Option, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), super::DatabaseError> { if let Some(permissions) = new_permissions { sqlx::query!( @@ -449,7 +449,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -464,7 +464,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -479,7 +479,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -495,7 +495,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -510,7 +510,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -525,7 +525,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -540,7 +540,7 @@ impl DBTeamMember { id as DBTeamId, user_id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } @@ -554,7 +554,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let accepted = if allow_pending { vec![true, false] @@ -607,7 +607,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let accepted = if allow_pending { vec![true, false] @@ -658,7 +658,7 @@ impl DBTeamMember { executor: E, ) -> Result, super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let result = sqlx::query!( " @@ -707,7 +707,7 @@ impl DBTeamMember { executor: E, ) -> Result<(Option, Option), super::DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let project_team_member = Self::get_from_user_id(project.team_id, user_id, executor).await?; diff --git a/apps/labrinth/src/database/models/thread_item.rs b/apps/labrinth/src/database/models/thread_item.rs index d01a1b384..ddded450a 100644 --- a/apps/labrinth/src/database/models/thread_item.rs +++ b/apps/labrinth/src/database/models/thread_item.rs @@ -1,4 +1,5 @@ use super::ids::*; +use crate::database::PgTransaction; use crate::database::models::DatabaseError; use crate::models::threads::{MessageBody, ThreadType}; use chrono::{DateTime, Utc}; @@ -43,7 +44,7 @@ pub struct DBThreadMessage { impl ThreadMessageBuilder { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let thread_message_id = generate_thread_message_id(transaction).await?; @@ -62,7 +63,7 @@ impl ThreadMessageBuilder { self.thread_id as DBThreadId, self.hide_identity ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(thread_message_id) @@ -72,7 +73,7 @@ impl ThreadMessageBuilder { impl ThreadBuilder { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let thread_id = generate_thread_id(&mut *transaction).await?; sqlx::query!( @@ -89,7 +90,7 @@ impl ThreadBuilder { self.project_id.map(|x| x.0), self.report_id.map(|x| x.0), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let (thread_ids, members): (Vec<_>, Vec<_>) = @@ -104,7 +105,7 @@ impl ThreadBuilder { &thread_ids[..], &members[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(thread_id) @@ -117,7 +118,7 @@ impl DBThread { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { Self::get_many(&[id], exec) .await @@ -129,7 +130,7 @@ impl DBThread { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { use futures::stream::TryStreamExt; @@ -173,7 +174,7 @@ impl DBThread { pub async fn remove_full( id: DBThreadId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::error::Error> { sqlx::query!( " @@ -182,7 +183,7 @@ impl DBThread { ", id as DBThreadId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( " @@ -191,7 +192,7 @@ impl DBThread { ", id as DBThreadId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( " @@ -200,7 +201,7 @@ impl DBThread { ", id as DBThreadId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) @@ -213,7 +214,7 @@ impl DBThreadMessage { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Self::get_many(&[id], exec) .await @@ -225,7 +226,7 @@ impl DBThreadMessage { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -257,7 +258,7 @@ impl DBThreadMessage { pub async fn remove_full( id: DBThreadMessageId, private: bool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, sqlx::error::Error> { sqlx::query!( " @@ -269,7 +270,7 @@ impl DBThreadMessage { serde_json::to_value(MessageBody::Deleted { private }) .unwrap_or(serde_json::json!({})) ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/user_item.rs b/apps/labrinth/src/database/models/user_item.rs index b28e005c8..df37dc243 100644 --- a/apps/labrinth/src/database/models/user_item.rs +++ b/apps/labrinth/src/database/models/user_item.rs @@ -1,10 +1,10 @@ use super::ids::{DBProjectId, DBUserId}; use super::{DBCollectionId, DBReportId, DBThreadId}; -use crate::database::models; use crate::database::models::charge_item::DBCharge; use crate::database::models::user_subscription_item::DBUserSubscription; use crate::database::models::{DBOrganizationId, DatabaseError}; use crate::database::redis::RedisPool; +use crate::database::{PgTransaction, models}; use crate::models::billing::ChargeStatus; use crate::models::users::Badges; use ariadne::ids::base62_impl::{parse_base62, to_base62}; @@ -56,7 +56,7 @@ pub struct DBUser { impl DBUser { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { sqlx::query!( " @@ -97,7 +97,7 @@ impl DBUser { self.allow_friend_requests, self.is_subscribed_to_newsletter, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -109,7 +109,7 @@ impl DBUser { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBUser::get_many(&[string], executor, redis) .await @@ -122,7 +122,7 @@ impl DBUser { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { DBUser::get_many(&[ariadne::ids::UserId::from(id)], executor, redis) .await @@ -135,7 +135,7 @@ impl DBUser { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let ids = user_ids .iter() @@ -154,7 +154,7 @@ impl DBUser { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::TryStreamExt; @@ -233,7 +233,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let user = sqlx::query!( " @@ -254,7 +254,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let users = sqlx::query!( " @@ -276,7 +276,7 @@ impl DBUser { exec: E, ) -> Result where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { let ids = user_ids.iter().map(|x| x.0).collect::>(); let count = sqlx::query_scalar!( @@ -295,7 +295,7 @@ impl DBUser { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -347,7 +347,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -372,7 +372,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -396,7 +396,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -420,7 +420,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -444,7 +444,7 @@ impl DBUser { exec: E, ) -> Result, sqlx::Error> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { use futures::stream::TryStreamExt; @@ -502,10 +502,10 @@ impl DBUser { pub async fn remove( id: DBUserId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result, DatabaseError> { - let user = Self::get_id(id, &mut **transaction, redis).await?; + let user = Self::get_id(id, &mut *transaction, redis).await?; if let Some(delete_user) = user { DBUser::clear_caches(&[(id, Some(delete_user.username))], redis) @@ -523,7 +523,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -535,7 +535,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -547,7 +547,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; use futures::TryStreamExt; @@ -558,7 +558,7 @@ impl DBUser { ", id as DBUserId, ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|m| m.id) .try_collect::>() .await?; @@ -570,7 +570,7 @@ impl DBUser { ", ¬ifications ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -580,7 +580,7 @@ impl DBUser { ", id as DBUserId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -590,7 +590,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let user_collections = sqlx::query!( @@ -601,7 +601,7 @@ impl DBUser { ", id as DBUserId, ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|x| DBCollectionId(x.id)) .try_collect::>() .await?; @@ -620,7 +620,7 @@ impl DBUser { ", id as DBUserId, ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|x| DBThreadId(x.id)) .try_collect::>() .await?; @@ -636,7 +636,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -648,7 +648,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -658,7 +658,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -668,7 +668,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -678,7 +678,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -690,7 +690,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -702,7 +702,7 @@ impl DBUser { id as DBUserId, deleted_user as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -712,7 +712,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -724,7 +724,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -734,7 +734,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -744,7 +744,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -754,7 +754,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -765,7 +765,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -774,7 +774,7 @@ impl DBUser { WHERE affiliate = $1", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -785,7 +785,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -794,16 +794,15 @@ impl DBUser { WHERE user_id = $1", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let open_subscriptions = - DBUserSubscription::get_all_user(id, &mut **transaction) - .await?; + DBUserSubscription::get_all_user(id, &mut *transaction).await?; for x in open_subscriptions { let charge = - DBCharge::get_open_subscription(x.id, &mut **transaction) + DBCharge::get_open_subscription(x.id, &mut *transaction) .await?; if let Some(mut charge) = charge { charge.status = ChargeStatus::Cancelled; @@ -823,7 +822,7 @@ impl DBUser { deleted_user as DBUserId, id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -833,7 +832,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -843,7 +842,7 @@ impl DBUser { ", id as DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(Some(())) diff --git a/apps/labrinth/src/database/models/user_limits.rs b/apps/labrinth/src/database/models/user_limits.rs index efd536c85..d612d2460 100644 --- a/apps/labrinth/src/database/models/user_limits.rs +++ b/apps/labrinth/src/database/models/user_limits.rs @@ -1,5 +1,5 @@ +use crate::database::PgPool; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use crate::database::models::DBUserId; diff --git a/apps/labrinth/src/database/models/user_subscription_item.rs b/apps/labrinth/src/database/models/user_subscription_item.rs index 63eb66656..1035c6c7a 100644 --- a/apps/labrinth/src/database/models/user_subscription_item.rs +++ b/apps/labrinth/src/database/models/user_subscription_item.rs @@ -1,3 +1,4 @@ +use crate::database::PgTransaction; use crate::database::models::{ DBProductPriceId, DBUserId, DBUserSubscriptionId, DatabaseError, }; @@ -62,14 +63,14 @@ impl TryFrom for DBUserSubscription { impl DBUserSubscription { pub async fn get( id: DBUserSubscriptionId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { Ok(Self::get_many(&[id], exec).await?.into_iter().next()) } pub async fn get_many( ids: &[DBUserSubscriptionId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let ids = ids.iter().map(|id| id.0).collect_vec(); let ids_ref: &[i64] = &ids; @@ -88,7 +89,7 @@ impl DBUserSubscription { pub async fn get_all_user( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let user_id = user_id.0; let results = select_user_subscriptions_with_predicate!( @@ -106,7 +107,7 @@ impl DBUserSubscription { pub async fn get_all_servers( status: Option, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let status = status.map(|x| x.as_str()); @@ -130,7 +131,7 @@ impl DBUserSubscription { pub async fn upsert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { sqlx::query!( " @@ -155,7 +156,7 @@ impl DBUserSubscription { self.status.as_str(), serde_json::to_value(&self.metadata)?, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -163,7 +164,7 @@ impl DBUserSubscription { pub async fn get_many_by_server_ids( server_ids: &[String], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { if server_ids.is_empty() { return Ok(vec![]); diff --git a/apps/labrinth/src/database/models/users_notifications_preferences_item.rs b/apps/labrinth/src/database/models/users_notifications_preferences_item.rs index c8014c7e6..1ba5e1ce0 100644 --- a/apps/labrinth/src/database/models/users_notifications_preferences_item.rs +++ b/apps/labrinth/src/database/models/users_notifications_preferences_item.rs @@ -39,14 +39,14 @@ impl From impl UserNotificationPreference { pub async fn get_user_or_default( user_id: DBUserId, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { Self::get_many_users_or_default(&[user_id], exec).await } pub async fn get_many_users_or_default( user_ids: &[DBUserId], - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result, DatabaseError> { let results = sqlx::query!( r#" @@ -86,7 +86,7 @@ impl UserNotificationPreference { /// Inserts the row into the table and updates its ID. pub async fn insert( &mut self, - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), DatabaseError> { let id = sqlx::query_scalar!( " diff --git a/apps/labrinth/src/database/models/users_subscriptions_credits.rs b/apps/labrinth/src/database/models/users_subscriptions_credits.rs index 1c96410c2..89d11c1b4 100644 --- a/apps/labrinth/src/database/models/users_subscriptions_credits.rs +++ b/apps/labrinth/src/database/models/users_subscriptions_credits.rs @@ -1,4 +1,7 @@ -use crate::database::models::{DBUserId, DBUserSubscriptionId}; +use crate::database::{ + PgTransaction, + models::{DBUserId, DBUserSubscriptionId}, +}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::query_scalar; @@ -43,7 +46,7 @@ impl DBUserSubscriptionCredit { } pub async fn insert_many( - exec: &mut sqlx::Transaction<'_, sqlx::Postgres>, + exec: &mut PgTransaction<'_>, subscription_ids: &[DBUserSubscriptionId], user_ids: &[DBUserId], creditor_ids: &[DBUserId], @@ -74,7 +77,7 @@ impl DBUserSubscriptionCredit { &previous_dues[..], &next_dues[..], ) - .execute(&mut **exec) + .execute(&mut *exec) .await?; Ok(()) diff --git a/apps/labrinth/src/database/models/version_item.rs b/apps/labrinth/src/database/models/version_item.rs index d0ba9c0b9..b6f18ee0e 100644 --- a/apps/labrinth/src/database/models/version_item.rs +++ b/apps/labrinth/src/database/models/version_item.rs @@ -1,6 +1,7 @@ use super::DatabaseError; use super::ids::*; use super::loader_fields::VersionField; +use crate::database::PgTransaction; use crate::database::models::loader_fields::{ QueryLoaderField, QueryLoaderFieldEnumValue, QueryVersionField, }; @@ -50,7 +51,7 @@ impl DependencyBuilder { pub async fn insert_many( builders: Vec, version_id: DBVersionId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let mut project_ids = Vec::new(); for dependency in &builders { @@ -89,7 +90,7 @@ impl DependencyBuilder { &project_ids[..] as &[Option], &filenames[..] as &[Option], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -97,7 +98,7 @@ impl DependencyBuilder { async fn try_get_project_id( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, DatabaseError> { Ok(if let Some(project_id) = self.project_id { Some(project_id) @@ -108,7 +109,7 @@ impl DependencyBuilder { ", version_id as DBVersionId, ) - .fetch_optional(&mut **transaction) + .fetch_optional(&mut *transaction) .await? .map(|x| DBProjectId(x.mod_id)) } else { @@ -131,7 +132,7 @@ impl VersionFileBuilder { pub async fn insert( self, version_id: DBVersionId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let file_id = generate_file_id(&mut *transaction).await?; @@ -148,7 +149,7 @@ impl VersionFileBuilder { self.size as i32, self.file_type.map(|x| x.as_str()), ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; for hash in self.hashes { @@ -161,12 +162,12 @@ impl VersionFileBuilder { hash.algorithm, hash.hash, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } if let Err(err) = crate::routes::internal::delphi::run( - &mut **transaction, + &mut *transaction, DelphiRunParameters { file_id: file_id.into(), }, @@ -189,7 +190,7 @@ pub struct HashBuilder { impl VersionBuilder { pub async fn insert( self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let version = DBVersion { id: self.version_id, @@ -217,7 +218,7 @@ impl VersionBuilder { ", self.project_id as DBProjectId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let VersionBuilder { @@ -263,7 +264,7 @@ pub struct DBLoaderVersion { impl DBLoaderVersion { pub async fn insert_many( items: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let (loader_ids, version_ids): (Vec<_>, Vec<_>) = items .iter() @@ -277,7 +278,7 @@ impl DBLoaderVersion { &loader_ids[..], &version_ids[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -304,7 +305,7 @@ pub struct DBVersion { impl DBVersion { pub async fn insert( &self, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), sqlx::error::Error> { sqlx::query!( " @@ -332,7 +333,7 @@ impl DBVersion { self.status.as_str(), self.ordering ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) @@ -341,9 +342,9 @@ impl DBVersion { pub async fn remove_full( id: DBVersionId, redis: &RedisPool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, DatabaseError> { - let result = Self::get(id, &mut **transaction, redis).await?; + let result = Self::get(id, &mut *transaction, redis).await?; let Some(result) = result else { return Ok(None); @@ -359,7 +360,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -369,7 +370,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -379,7 +380,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -393,7 +394,7 @@ impl DBVersion { ", id as DBVersionId ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -403,7 +404,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; // Sync dependencies @@ -414,7 +415,7 @@ impl DBVersion { ", id as DBVersionId, ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await?; sqlx::query!( @@ -426,7 +427,7 @@ impl DBVersion { id as DBVersionId, project_id.mod_id, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -434,7 +435,7 @@ impl DBVersion { DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL AND dependency_file_name = NULL ", ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; sqlx::query!( @@ -443,7 +444,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; // delete version @@ -454,7 +455,7 @@ impl DBVersion { ", id as DBVersionId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; crate::database::models::DBProject::clear_cache( @@ -474,7 +475,7 @@ impl DBVersion { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { Self::get_many(&[id], executor, redis) .await @@ -487,7 +488,7 @@ impl DBVersion { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { let mut val = redis.get_cached_keys( VERSIONS_NAMESPACE, @@ -504,7 +505,7 @@ impl DBVersion { ", &version_ids ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold( DashMap::new(), |acc: DashMap>, m| { @@ -554,7 +555,7 @@ impl DBVersion { GROUP BY version_id ", &version_ids - ).fetch(&mut *exec) + ).fetch(&mut exec) .map_ok(|m| { let version_id = DBVersionId(m.version_id); @@ -585,7 +586,7 @@ impl DBVersion { ", &loader_field_ids.iter().map(|x| x.0).collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .map_ok(|m| QueryLoaderField { id: LoaderFieldId(m.id), field: m.field, @@ -610,7 +611,7 @@ impl DBVersion { .map(|x| x.0) .collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .map_ok(|m| QueryLoaderFieldEnumValue { id: LoaderFieldEnumValueId(m.id), enum_id: LoaderFieldEnumId(m.enum_id), @@ -648,7 +649,7 @@ impl DBVersion { WHERE f.version_id = ANY($1) ", &version_ids - ).fetch(&mut *exec) + ).fetch(&mut exec) .try_fold(DashMap::new(), |acc : DashMap>, m| { let file = File { id: DBFileId(m.id), @@ -677,7 +678,7 @@ impl DBVersion { ", &file_ids.iter().map(|x| x.0).collect::>() ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold(DashMap::new(), |acc: DashMap>, m| { if let Some(found_hash) = m.hash { let hash = Hash { @@ -701,7 +702,7 @@ impl DBVersion { WHERE dependent_id = ANY($1) ", &version_ids - ).fetch(&mut *exec) + ).fetch(&mut exec) .try_fold(DashMap::new(), |acc : DashMap<_,Vec>, m| { let dependency = DependencyQueryResult { project_id: m.dependency_project_id.map(DBProjectId), @@ -727,7 +728,7 @@ impl DBVersion { ", &version_ids ) - .fetch(&mut *exec) + .fetch(&mut exec) .try_fold(DashMap::new(), |acc, v| { let version_id = DBVersionId(v.id); let VersionLoaderData { @@ -827,7 +828,7 @@ impl DBVersion { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { Self::get_files_from_hash(algo, &[hash], executor, redis) .await @@ -844,7 +845,7 @@ impl DBVersion { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy, + E: crate::database::Executor<'a, Database = sqlx::Postgres> + Copy, { let val = redis.get_cached_keys( VERSION_FILES_NAMESPACE, diff --git a/apps/labrinth/src/database/postgres_database.rs b/apps/labrinth/src/database/postgres_database.rs index 7d6bed130..a0f4d4573 100644 --- a/apps/labrinth/src/database/postgres_database.rs +++ b/apps/labrinth/src/database/postgres_database.rs @@ -1,12 +1,23 @@ use eyre::Context; use prometheus::{IntGauge, Registry}; use sqlx::migrate::{MigrateDatabase, Migrator}; -use sqlx::postgres::{PgPool, PgPoolOptions}; -use sqlx::{Connection, PgConnection, Postgres}; +use sqlx::postgres::PgPoolOptions; +use sqlx::{Connection, Postgres}; use std::ops::{Deref, DerefMut}; use std::time::Duration; use tracing::info; +// TODO tracing spans +pub type PgPool = sqlx_tracing::Pool; +pub type PgTransaction<'c> = sqlx_tracing::Transaction<'c, Postgres>; +pub use sqlx_tracing::Acquire; +pub use sqlx_tracing::Executor; + +// pub type PgPool = sqlx::PgPool; +// pub type PgTransaction<'c> = sqlx::Transaction<'c, Postgres>; +// pub use sqlx::Acquire; +// pub use sqlx::Executor; + #[derive(Clone)] #[repr(transparent)] pub struct ReadOnlyPgPool(PgPool); @@ -71,6 +82,7 @@ pub async fn connect_all() -> Result<(PgPool, ReadOnlyPgPool), sqlx::Error> { .max_lifetime(Some(Duration::from_secs(60 * 60))) .connect(&database_url) .await?; + let pool = PgPool::from(pool); if let Ok(url) = dotenvy::var("READONLY_DATABASE_URL") { let ro_pool = PgPoolOptions::new() @@ -90,6 +102,7 @@ pub async fn connect_all() -> Result<(PgPool, ReadOnlyPgPool), sqlx::Error> { .max_lifetime(Some(Duration::from_secs(60 * 60))) .connect(&url) .await?; + let ro_pool = PgPool::from(ro_pool); Ok((pool, ReadOnlyPgPool(ro_pool))) } else { @@ -114,9 +127,10 @@ pub async fn check_for_migrations() -> eyre::Result<()> { info!("Applying migrations..."); - let mut conn: PgConnection = PgConnection::connect(uri) - .await - .wrap_err("failed to connect to database")?; + let mut conn: sqlx::PgConnection = + sqlx::PgConnection::connect(uri) + .await + .wrap_err("failed to connect to database")?; MIGRATOR .run(&mut conn) .await diff --git a/apps/labrinth/src/lib.rs b/apps/labrinth/src/lib.rs index 4376f2c20..851798756 100644 --- a/apps/labrinth/src/lib.rs +++ b/apps/labrinth/src/lib.rs @@ -7,7 +7,6 @@ use queue::{ analytics::AnalyticsQueue, email::EmailQueue, payouts::PayoutsQueue, session::AuthQueue, socket::ActiveSockets, }; -use sqlx::Postgres; use tracing::{debug, info, warn}; extern crate clickhouse as clickhouse_crate; @@ -16,7 +15,7 @@ use util::cors::default_cors; use util::gotenberg::GotenbergClient; use crate::background_task::update_versions; -use crate::database::ReadOnlyPgPool; +use crate::database::{PgPool, ReadOnlyPgPool}; use crate::queue::billing::{index_billing, index_subscriptions}; use crate::queue::moderation::AutomatedModerationQueue; use crate::search::MeilisearchReadClient; @@ -50,7 +49,7 @@ pub struct Pepper { #[derive(Clone)] pub struct LabrinthConfig { - pub pool: sqlx::Pool, + pub pool: PgPool, pub ro_pool: ReadOnlyPgPool, pub redis_pool: RedisPool, pub clickhouse: Client, @@ -74,7 +73,7 @@ pub struct LabrinthConfig { #[allow(clippy::too_many_arguments)] pub fn app_setup( - pool: sqlx::Pool, + pool: PgPool, ro_pool: ReadOnlyPgPool, redis_pool: RedisPool, search_config: search::SearchConfig, diff --git a/apps/labrinth/src/models/v2/projects.rs b/apps/labrinth/src/models/v2/projects.rs index ef4c48454..2d09669a6 100644 --- a/apps/labrinth/src/models/v2/projects.rs +++ b/apps/labrinth/src/models/v2/projects.rs @@ -231,7 +231,7 @@ impl LegacyProject { redis: &RedisPool, ) -> Result, DatabaseError> where - E: sqlx::Acquire<'a, Database = sqlx::Postgres>, + E: crate::database::Acquire<'a, Database = sqlx::Postgres>, { let version_ids: Vec<_> = data .iter() diff --git a/apps/labrinth/src/models/v3/user_limits.rs b/apps/labrinth/src/models/v3/user_limits.rs index c9c69f1e0..ac7c08e53 100644 --- a/apps/labrinth/src/models/v3/user_limits.rs +++ b/apps/labrinth/src/models/v3/user_limits.rs @@ -1,5 +1,5 @@ +use crate::database::PgPool; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use crate::{ database::models::{DBUserId, user_limits::DBUserLimits}, diff --git a/apps/labrinth/src/queue/analytics.rs b/apps/labrinth/src/queue/analytics.rs index bb0373cb4..f471b0821 100644 --- a/apps/labrinth/src/queue/analytics.rs +++ b/apps/labrinth/src/queue/analytics.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; use crate::models::analytics::{ @@ -6,7 +7,6 @@ use crate::models::analytics::{ use crate::routes::ApiError; use dashmap::{DashMap, DashSet}; use redis::cmd; -use sqlx::PgPool; use std::collections::HashMap; const DOWNLOADS_NAMESPACE: &str = "downloads"; @@ -255,7 +255,7 @@ impl AnalyticsQueue { ) .bind(version_downloads.keys().copied().collect::>()) .bind(version_downloads.values().copied().collect::>()) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query( @@ -268,7 +268,7 @@ impl AnalyticsQueue { ) .bind(project_downloads.keys().copied().collect::>()) .bind(project_downloads.values().copied().collect::>()) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/queue/billing.rs b/apps/labrinth/src/queue/billing.rs index dfa7b02dd..c529e9f57 100644 --- a/apps/labrinth/src/queue/billing.rs +++ b/apps/labrinth/src/queue/billing.rs @@ -11,6 +11,7 @@ use crate::database::models::{ product_item, user_subscription_item, users_redeemals, }; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::models::billing::{ ChargeStatus, ChargeType, PaymentPlatform, Price, PriceDuration, ProductMetadata, SubscriptionMetadata, SubscriptionStatus, @@ -28,7 +29,6 @@ use ariadne::ids::base62_impl::to_base62; use chrono::Utc; use futures::FutureExt; use futures::stream::{FuturesUnordered, StreamExt}; -use sqlx::PgPool; use std::collections::HashSet; use std::str::FromStr; use std::time::Instant; @@ -49,7 +49,7 @@ async fn update_tax_amounts( loop { let mut txn = pg.begin().await?; - let charges = DBCharge::get_updateable_lock(&mut *txn, 5).await?; + let charges = DBCharge::get_updateable_lock(&mut txn, 5).await?; if charges.is_empty() { info!("No more charges to process"); @@ -273,7 +273,7 @@ async fn update_anrok_transactions( ) -> Result<(), ApiError> { async fn process_charge( stripe_client: &stripe::Client, - txn: &mut sqlx::PgTransaction<'_>, + txn: &mut PgTransaction<'_>, redis: &RedisPool, anrok_client: &anrok::Client, mut c: DBCharge, @@ -341,7 +341,7 @@ async fn update_anrok_transactions( .and_then(|x| x.billing_details.address); let stripe_customer_id = - DBUser::get_id(c.user_id, &mut **txn, redis) + DBUser::get_id(c.user_id, &mut *txn, redis) .await? .ok_or_else(|| { ApiError::from(DatabaseError::Database( @@ -395,7 +395,7 @@ async fn update_anrok_transactions( (address, tax_platform_id, customer_id) }; - let tax_id = DBProductsTaxIdentifier::get_price(c.price_id, &mut **txn) + let tax_id = DBProductsTaxIdentifier::get_price(c.price_id, &mut *txn) .await? .ok_or_else(|| DatabaseError::Database(sqlx::Error::RowNotFound))?; @@ -466,7 +466,7 @@ async fn update_anrok_transactions( let mut txn = pg.begin().await?; let mut charges = - DBCharge::get_missing_tax_identifier_lock(&mut *txn, offset, 1) + DBCharge::get_missing_tax_identifier_lock(&mut txn, offset, 1) .await?; let Some(c) = charges.pop() else { @@ -654,7 +654,7 @@ pub async fn try_process_user_redeemal( // Update `users_redeemal`, mark subscription as redeemed. user_redeemal.status = users_redeemals::Status::Processed; - user_redeemal.update(&mut *txn).await?; + user_redeemal.update(&mut txn).await?; txn.commit().await?; @@ -896,7 +896,7 @@ async fn unprovision_subscriptions( badges.bits() as i64, user.id as DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; true @@ -942,7 +942,7 @@ async fn unprovision_subscriptions( DBUsersSubscriptionsAffiliations::deactivate( subscription.id, - &mut *transaction, + &mut transaction, ) .await .wrap_internal_err( diff --git a/apps/labrinth/src/queue/email.rs b/apps/labrinth/src/queue/email.rs index 099eb278f..554b91ed4 100644 --- a/apps/labrinth/src/queue/email.rs +++ b/apps/labrinth/src/queue/email.rs @@ -4,6 +4,7 @@ use crate::database::models::notifications_deliveries_item::DBNotificationDelive use crate::database::models::notifications_template_item::NotificationTemplate; use crate::database::models::user_item::DBUser; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::models::notifications::{NotificationBody, NotificationType}; use crate::models::v3::notifications::{ NotificationChannel, NotificationDeliveryStatus, @@ -16,7 +17,6 @@ use lettre::transport::smtp::authentication::Credentials; use lettre::transport::smtp::client::{Tls, TlsParameters}; use lettre::{AsyncSmtpTransport, AsyncTransport, Tokio1Executor}; use reqwest::Client; -use sqlx::PgPool; use std::sync::Arc; use thiserror::Error; use tokio::sync::Mutex as TokioMutex; @@ -204,12 +204,9 @@ impl EmailQueue { futures.push(async move { let mut txn = this.pg.begin().await?; - let maybe_user = DBUser::get_id( - notification.user_id, - &mut *txn, - &this.redis, - ) - .await?; + let maybe_user = + DBUser::get_id(notification.user_id, &mut txn, &this.redis) + .await?; let Some(mailbox) = maybe_user .and_then(|user| user.email) @@ -301,7 +298,7 @@ impl EmailQueue { pub async fn send_one( &self, - txn: &mut sqlx::PgTransaction<'_>, + txn: &mut PgTransaction<'_>, notification: NotificationBody, user_id: DBUserId, address: Mailbox, @@ -319,7 +316,7 @@ impl EmailQueue { async fn send_one_with_transport( &self, - txn: &mut sqlx::PgTransaction<'_>, + txn: &mut PgTransaction<'_>, transport: Arc>, notification: NotificationBody, user_id: DBUserId, @@ -330,7 +327,7 @@ impl EmailQueue { let Some(template) = NotificationTemplate::list_channel( NotificationChannel::Email, - &mut **txn, + &mut *txn, &self.redis, ) .await? diff --git a/apps/labrinth/src/queue/email/templates.rs b/apps/labrinth/src/queue/email/templates.rs index dafcd15b2..3815db40d 100644 --- a/apps/labrinth/src/queue/email/templates.rs +++ b/apps/labrinth/src/queue/email/templates.rs @@ -1,4 +1,5 @@ use super::MailError; +use crate::database::PgTransaction; use crate::database::models::ids::*; use crate::database::models::notifications_template_item::{ NotificationTemplate, get_or_set_cached_dynamic_html, @@ -105,7 +106,7 @@ impl MailingIdentity { #[allow(clippy::too_many_arguments)] pub async fn build_email( - exec: &mut sqlx::PgTransaction<'_>, + exec: &mut PgTransaction<'_>, redis: &RedisPool, client: &reqwest::Client, user_id: DBUserId, @@ -147,7 +148,7 @@ pub async fn build_email( reply_address, } = from; - let db_user = DBUser::get_id(user_id, &mut **exec, redis) + let db_user = DBUser::get_id(user_id, &mut *exec, redis) .await? .ok_or(DatabaseError::Database(sqlx::Error::RowNotFound))?; @@ -297,7 +298,7 @@ enum EmailTemplate { } async fn collect_template_variables( - exec: &mut sqlx::PgTransaction<'_>, + exec: &mut PgTransaction<'_>, redis: &RedisPool, user_id: DBUserId, n: &NotificationBody, @@ -339,7 +340,7 @@ async fn collect_template_variables( "#, report_id.0 as i64 ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(REPORT_ID, to_base62(report_id.0)); @@ -361,7 +362,7 @@ async fn collect_template_variables( "#, report_id.0 as i64 ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(REPORT_TITLE, result.title); @@ -376,7 +377,7 @@ async fn collect_template_variables( "#, project_id.0 as i64 ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(PROJECT_ID, to_base62(project_id.0)); @@ -414,7 +415,7 @@ async fn collect_template_variables( } => { let project = DBProject::get_id( DBProjectId(project_id.0 as i64), - &mut **exec, + &mut *exec, redis, ) .await? @@ -428,7 +429,7 @@ async fn collect_template_variables( if let Some(new_owner_user_id) = new_owner_user_id { let user = DBUser::get_id( DBUserId(new_owner_user_id.0 as i64), - &mut **exec, + &mut *exec, redis, ) .await? @@ -444,7 +445,7 @@ async fn collect_template_variables( { let org = DBOrganization::get_id( DBOrganizationId(new_owner_organization_id.0 as i64), - &mut **exec, + &mut *exec, redis, ) .await? @@ -484,7 +485,7 @@ async fn collect_template_variables( project_id.0 as i64, user_id.0 as i64 ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(TEAMINVITE_INVITER_NAME, result.inviter_name); @@ -516,7 +517,7 @@ async fn collect_template_variables( organization_id.0 as i64, user_id.0 as i64 ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(ORGINVITE_INVITER_NAME, result.inviter_name); @@ -544,7 +545,7 @@ async fn collect_template_variables( project_id.0 as i64, user_id.0 as i64, ) - .fetch_one(&mut **exec) + .fetch_one(&mut *exec) .await?; map.insert(STATUSCHANGE_PROJECT_NAME, result.project_name); @@ -706,12 +707,12 @@ async fn collect_template_variables( // Resolve product metadata via price_id join if let Some(info) = crate::database::models::user_subscription_item::DBUserSubscription::get( (*subscription_id).into(), - &mut **exec, + &mut *exec, ) .await .ok() .flatten() - && let Ok(Some(pinfo)) = crate::database::models::products_tax_identifier_item::product_info_by_product_price_id(info.price_id, &mut **exec).await { + && let Ok(Some(pinfo)) = crate::database::models::products_tax_identifier_item::product_info_by_product_price_id(info.price_id, &mut *exec).await { let label = match pinfo.product_metadata { crate::models::billing::ProductMetadata::Pyro { .. } => "server".to_string(), crate::models::billing::ProductMetadata::Medal { .. } => "server".to_string(), diff --git a/apps/labrinth/src/queue/moderation.rs b/apps/labrinth/src/queue/moderation.rs index cb17fe841..21ced3616 100644 --- a/apps/labrinth/src/queue/moderation.rs +++ b/apps/labrinth/src/queue/moderation.rs @@ -1,5 +1,6 @@ use crate::auth::checks::filter_visible_versions; use crate::database; +use crate::database::PgPool; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::thread_item::ThreadMessageBuilder; use crate::database::redis::RedisPool; @@ -14,7 +15,6 @@ use hex::ToHex; use itertools::Itertools; use serde::{Deserialize, Serialize}; use sha1::Digest; -use sqlx::PgPool; use std::collections::HashMap; use std::fmt::Write; use std::io::{Cursor, Read}; diff --git a/apps/labrinth/src/queue/payouts/affiliate.rs b/apps/labrinth/src/queue/payouts/affiliate.rs index 61adf1ab4..980b18b0f 100644 --- a/apps/labrinth/src/queue/payouts/affiliate.rs +++ b/apps/labrinth/src/queue/payouts/affiliate.rs @@ -1,7 +1,7 @@ +use crate::database::PgPool; use chrono::{Datelike, Duration, TimeZone, Utc}; use eyre::{Context, Result, eyre}; use rust_decimal::{Decimal, dec}; -use sqlx::PgPool; use tracing::warn; use crate::database::models::{DBAffiliateCodeId, DBUserId}; @@ -58,7 +58,7 @@ pub async fn process_affiliate_payouts(postgres: &PgPool) -> Result<()> { ) "# ) - .fetch_all(&mut *txn) + .fetch_all(&mut txn) .await .wrap_err("failed to fetch charges awaiting affiliate payout")?; @@ -147,7 +147,7 @@ pub async fn process_affiliate_payouts(postgres: &PgPool) -> Result<()> { available, affiliate_code_id as _, ) - .fetch_one(&mut *txn) + .fetch_one(&mut txn) .await .wrap_err_with(|| eyre!("failed to insert payout value for ({affiliate_user_id:?}, {affiliate_code_id:?})"))? .id; @@ -170,7 +170,7 @@ pub async fn process_affiliate_payouts(postgres: &PgPool) -> Result<()> { &insert_usap_affiliate_codes[..], &insert_usap_payout_values[..], ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_err("failed to associate charges with affiliate payouts")?; @@ -221,7 +221,7 @@ pub async fn remove_payouts_for_refunded_charges( AND refund_charges.charge_type = 'refund' "# ) - .fetch_all(&mut *txn) + .fetch_all(&mut txn) .await .wrap_err("failed to fetch refundable affiliate payouts")?; @@ -248,7 +248,7 @@ pub async fn remove_payouts_for_refunded_charges( ", &usap_ids[..] ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_err("failed to delete affiliate payout associations")?; @@ -260,7 +260,7 @@ pub async fn remove_payouts_for_refunded_charges( ", &payout_value_ids[..] ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_err("failed to delete payout values")?; diff --git a/apps/labrinth/src/queue/payouts/flow/mod.rs b/apps/labrinth/src/queue/payouts/flow/mod.rs index 44555cd3c..08c8d7776 100644 --- a/apps/labrinth/src/queue/payouts/flow/mod.rs +++ b/apps/labrinth/src/queue/payouts/flow/mod.rs @@ -4,7 +4,6 @@ use eyre::eyre; use modrinth_util::decimal::Decimal2dp; use rust_decimal::Decimal; -use sqlx::PgTransaction; use thiserror::Error; pub mod mural; @@ -12,7 +11,10 @@ pub mod paypal; pub mod tremendous; use crate::{ - database::models::{DBPayoutId, DBUser}, + database::{ + PgTransaction, + models::{DBPayoutId, DBUser}, + }, models::payouts::{PayoutMethodRequest, Withdrawal}, queue::payouts::PayoutsQueue, routes::ApiError, diff --git a/apps/labrinth/src/queue/payouts/mod.rs b/apps/labrinth/src/queue/payouts/mod.rs index 1402df6a8..cd6c38b8a 100644 --- a/apps/labrinth/src/queue/payouts/mod.rs +++ b/apps/labrinth/src/queue/payouts/mod.rs @@ -1,6 +1,7 @@ use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::payouts_values_notifications; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::models::payouts::{ PayoutDecimal, PayoutInterval, PayoutMethod, PayoutMethodType, TremendousForexResponse, @@ -26,7 +27,6 @@ use rust_decimal::prelude::ToPrimitive; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serde_json::Value; -use sqlx::PgPool; use sqlx::postgres::PgQueryResult; use std::collections::HashMap; use tokio::sync::RwLock; @@ -1023,7 +1023,7 @@ pub async fn process_payout( .map(|x| x.to_string()) .collect::>(), ) - .fetch(&mut *transaction) + .fetch(&mut transaction) .try_fold(DashMap::new(), |acc: DashMap>, r| { acc.entry(r.id) .or_default() @@ -1046,7 +1046,7 @@ pub async fn process_payout( .map(|x| x.to_string()) .collect::>(), ) - .fetch(&mut *transaction) + .fetch(&mut transaction) .try_fold( DashMap::new(), |acc: DashMap>, r| { @@ -1193,7 +1193,7 @@ pub async fn process_payout( &insert_starts[..], &insert_availables[..] ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1208,7 +1208,7 @@ pub async fn insert_payouts( insert_payouts: Vec, insert_starts: Vec>, insert_availables: Vec>, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> sqlx::Result { sqlx::query!( " @@ -1221,7 +1221,7 @@ pub async fn insert_payouts( &insert_starts[..], &insert_availables[..], ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await } @@ -1234,11 +1234,11 @@ pub async fn index_payouts_notifications( let mut transaction = pool.begin().await?; payouts_values_notifications::synchronize_future_payout_values( - &mut *transaction, + &mut transaction, 200, ) .await?; - let items = payouts_values_notifications::PayoutsValuesNotification::unnotified_users_with_available_payouts_with_limit(&mut *transaction, 200).await?; + let items = payouts_values_notifications::PayoutsValuesNotification::unnotified_users_with_available_payouts_with_limit(&mut transaction, 200).await?; let payout_ref_ids = items.iter().map(|x| x.id).collect::>(); let dates_available = @@ -1254,7 +1254,7 @@ pub async fn index_payouts_notifications( .await?; payouts_values_notifications::PayoutsValuesNotification::set_notified_many( &payout_ref_ids, - &mut *transaction, + &mut transaction, ) .await?; @@ -1320,7 +1320,7 @@ pub async fn insert_bank_balances_and_webhook( &insert_pending[..], &insert_recorded[..], ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if inserted { diff --git a/apps/labrinth/src/queue/payouts/mural.rs b/apps/labrinth/src/queue/payouts/mural.rs index 633da0811..8603c9de1 100644 --- a/apps/labrinth/src/queue/payouts/mural.rs +++ b/apps/labrinth/src/queue/payouts/mural.rs @@ -1,10 +1,10 @@ +use crate::database::PgPool; use chrono::Utc; use eyre::{Result, eyre}; use futures::{StreamExt, TryFutureExt, stream::FuturesUnordered}; use modrinth_util::decimal::Decimal2dp; use rust_decimal::{Decimal, prelude::ToPrimitive}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use tracing::{info, trace, warn}; use crate::{ @@ -177,7 +177,7 @@ pub async fn sync_pending_payouts_from_mural( .collect::>(), i64::from(limit), ) - .fetch_all(&mut *txn) + .fetch_all(&mut txn) .await .wrap_internal_err("failed to fetch incomplete Mural payouts")?; @@ -235,7 +235,7 @@ pub async fn sync_pending_payouts_from_mural( &payout_ids, &payout_statuses, ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_internal_err("failed to update payout statuses")?; @@ -452,7 +452,7 @@ mod tests { } async fn setup_test_db_with_payouts( - db: &sqlx::PgPool, + db: &PgPool, payouts: Vec<(i64, String, PayoutStatus)>, ) -> Result<(), eyre::Error> { for (id, platform_id, status) in payouts { diff --git a/apps/labrinth/src/queue/session.rs b/apps/labrinth/src/queue/session.rs index ed969d354..9952fd1e7 100644 --- a/apps/labrinth/src/queue/session.rs +++ b/apps/labrinth/src/queue/session.rs @@ -4,10 +4,10 @@ use crate::database::models::{ DBOAuthAccessTokenId, DBPatId, DBSessionId, DBUserId, DatabaseError, }; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::routes::internal::session::SessionMetadata; use chrono::Utc; use itertools::Itertools; -use sqlx::PgPool; use std::collections::{HashMap, HashSet}; use tokio::sync::Mutex; @@ -55,14 +55,14 @@ impl AuthQueue { let mut queue = self.session_queue.lock().await; let len = queue.len(); - std::mem::replace(&mut queue, HashMap::with_capacity(len)) + std::mem::replace(&mut *queue, HashMap::with_capacity(len)) } pub async fn take_hashset(queue: &Mutex>) -> HashSet { let mut queue = queue.lock().await; let len = queue.len(); - std::mem::replace(&mut queue, HashSet::with_capacity(len)) + std::mem::replace(&mut *queue, HashSet::with_capacity(len)) } pub async fn index( @@ -100,7 +100,7 @@ impl AuthQueue { metadata.platform, metadata.user_agent, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -112,7 +112,7 @@ impl AuthQueue { WHERE refresh_expires <= NOW() " ) - .fetch(&mut *transaction) + .fetch(&mut transaction) .map_ok(|x| (DBSessionId(x.id), x.session, DBUserId(x.user_id))) .try_collect::>() .await?; @@ -143,7 +143,7 @@ impl AuthQueue { &ids[..], Utc::now(), ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; update_oauth_access_token_last_used( @@ -162,7 +162,7 @@ impl AuthQueue { async fn update_oauth_access_token_last_used( oauth_access_token_queue: HashSet, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let ids = oauth_access_token_queue.iter().map(|id| id.0).collect_vec(); sqlx::query!( @@ -175,7 +175,7 @@ async fn update_oauth_access_token_last_used( &ids[..], Utc::now() ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; Ok(()) } diff --git a/apps/labrinth/src/routes/analytics.rs b/apps/labrinth/src/routes/analytics.rs index 501b8be21..09e95335a 100644 --- a/apps/labrinth/src/routes/analytics.rs +++ b/apps/labrinth/src/routes/analytics.rs @@ -1,4 +1,5 @@ use crate::auth::get_user_from_headers; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::analytics::{PageView, Playtime}; use crate::models::pats::Scopes; @@ -10,7 +11,6 @@ use crate::util::env::parse_strings_from_var; use actix_web::{HttpRequest, HttpResponse}; use actix_web::{post, web}; use serde::Deserialize; -use sqlx::PgPool; use std::collections::HashMap; use std::net::Ipv4Addr; use std::sync::Arc; diff --git a/apps/labrinth/src/routes/internal/admin.rs b/apps/labrinth/src/routes/internal/admin.rs index e94b30ab7..ecc230cff 100644 --- a/apps/labrinth/src/routes/internal/admin.rs +++ b/apps/labrinth/src/routes/internal/admin.rs @@ -1,4 +1,5 @@ use crate::auth::validate::get_user_record_from_bearer_token; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::analytics::Download; use crate::models::ids::ProjectId; @@ -11,7 +12,6 @@ use crate::util::date::get_current_tenths_of_ms; use crate::util::guards::admin_key_guard; use actix_web::{HttpRequest, HttpResponse, patch, post, web}; use serde::Deserialize; -use sqlx::PgPool; use std::collections::HashMap; use std::net::Ipv4Addr; use std::sync::Arc; diff --git a/apps/labrinth/src/routes/internal/affiliate.rs b/apps/labrinth/src/routes/internal/affiliate.rs index 18355d5a8..8f1e54fe6 100644 --- a/apps/labrinth/src/routes/internal/affiliate.rs +++ b/apps/labrinth/src/routes/internal/affiliate.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, net::Ipv4Addr, sync::Arc}; +use crate::database::PgPool; use crate::{ auth::get_user_from_headers, database::{ @@ -21,7 +22,6 @@ use actix_web::{HttpRequest, delete, get, patch, post, put, web}; use ariadne::ids::UserId; use chrono::Utc; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use tracing::trace; use url::Url; @@ -254,7 +254,7 @@ async fn create( affiliate: affiliate_id, source_name: body.source_name.clone(), }; - code.insert(&mut *transaction) + code.insert(&mut transaction) .await .wrap_internal_err("failed to insert affiliate code")?; diff --git a/apps/labrinth/src/routes/internal/billing.rs b/apps/labrinth/src/routes/internal/billing.rs index 5d2c7fbb5..e454634c0 100644 --- a/apps/labrinth/src/routes/internal/billing.rs +++ b/apps/labrinth/src/routes/internal/billing.rs @@ -11,6 +11,7 @@ use crate::database::models::{ user_subscription_item, }; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::models::billing::{ Charge, ChargeStatus, ChargeType, PaymentPlatform, Price, PriceDuration, Product, ProductMetadata, ProductPrice, SubscriptionMetadata, @@ -29,7 +30,6 @@ use chrono::{Duration, Utc}; use rust_decimal::Decimal; use rust_decimal::prelude::ToPrimitive; use serde::{Deserialize, Serialize}; -use sqlx::{PgPool, Postgres, Transaction}; use std::collections::HashMap; use std::str::FromStr; use stripe::{ @@ -449,7 +449,7 @@ pub async fn reprocess_charge_tax( let mut txn = pool.begin().await?; - let charge_refund = charge_item::DBCharge::get(id.into(), &mut *txn) + let charge_refund = charge_item::DBCharge::get(id.into(), &mut txn) .await? .ok_or_else(|| ApiError::NotFound)?; @@ -466,10 +466,9 @@ pub async fn reprocess_charge_tax( )); } None => { - let charge = - charge_item::DBCharge::get(parent_charge_id, &mut *txn) - .await? - .ok_or_else(|| ApiError::NotFound)?; + let charge = charge_item::DBCharge::get(parent_charge_id, &mut txn) + .await? + .ok_or_else(|| ApiError::NotFound)?; let payment_platform_id = charge .payment_platform_id @@ -503,7 +502,7 @@ pub async fn reprocess_charge_tax( }; let tax_id = - product_info_by_product_price_id(charge.price_id, &mut *txn) + product_info_by_product_price_id(charge.price_id, &mut txn) .await? .ok_or_else(|| { ApiError::InvalidInput( @@ -634,13 +633,13 @@ pub async fn edit_subscription( /// if this operation will require immediate payment or if the user can be /// charged only after the promotion interval ends. async fn promotion_payment_requirement( - txn: &mut sqlx::PgTransaction<'_>, + txn: &mut PgTransaction<'_>, current_product_price: &product_item::DBProductPrice, new_product_price: &product_item::DBProductPrice, ) -> Result { let new_product = product_item::DBProduct::get( new_product_price.product_id, - &mut **txn, + &mut *txn, ) .await? .ok_or_else(|| { @@ -650,7 +649,7 @@ pub async fn edit_subscription( })?; let current_product = product_item::DBProduct::get( current_product_price.product_id, - &mut **txn, + &mut *txn, ) .await? .ok_or_else(|| { @@ -769,7 +768,7 @@ pub async fn edit_subscription( let mut open_charge = charge_item::DBCharge::get_open_subscription( subscription.id, - &mut *transaction, + &mut transaction, ) .await? .ok_or_else(|| { @@ -780,7 +779,7 @@ pub async fn edit_subscription( let current_price = product_item::DBProductPrice::get( subscription.price_id, - &mut *transaction, + &mut transaction, ) .await? .ok_or_else(|| { @@ -798,7 +797,7 @@ pub async fn edit_subscription( if cancelled { DBUsersSubscriptionsAffiliations::deactivate( subscription.id, - &mut *transaction, + &mut transaction, ) .await?; open_charge.status = ChargeStatus::Cancelled; @@ -822,7 +821,7 @@ pub async fn edit_subscription( open_charge.status = if cancelled { DBUsersSubscriptionsAffiliations::deactivate( subscription.id, - &mut *transaction, + &mut transaction, ) .await?; ChargeStatus::Cancelled @@ -845,7 +844,7 @@ pub async fn edit_subscription( let new_product_price = product_item::DBProductPrice::get_all_product_prices( product_id.into(), - &mut *transaction, + &mut transaction, ) .await? .into_iter() @@ -1650,7 +1649,7 @@ pub async fn stripe_webhook( pool: &PgPool, redis: &RedisPool, charge_status: ChargeStatus, - transaction: &mut Transaction<'_, Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { 'metadata: { let Some(user_id) = metadata @@ -1977,7 +1976,7 @@ pub async fn stripe_webhook( metadata.user_item.id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } ProductMetadata::Pyro { @@ -2161,7 +2160,7 @@ pub async fn stripe_webhook( { let open_charge = DBCharge::get_open_subscription( subscription.id, - &mut *transaction, + &mut transaction, ) .await?; @@ -2269,7 +2268,7 @@ pub async fn stripe_webhook( ), deactivated_at: None, } - .insert(&mut *transaction) + .insert(&mut transaction) .await?; } }; @@ -2409,7 +2408,7 @@ pub async fn stripe_webhook( #[allow(clippy::too_many_arguments)] async fn apply_credit_many( - transaction: &mut Transaction<'_, Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, current_user_id: crate::database::models::ids::DBUserId, subscription_ids: Vec, @@ -2423,7 +2422,7 @@ async fn apply_credit_many( .collect(); let subs = user_subscription_item::DBUserSubscription::get_many( &subs_ids, - &mut **transaction, + &mut *transaction, ) .await?; @@ -2451,7 +2450,7 @@ async fn apply_credit_many( let mut open_charge = charge_item::DBCharge::get_open_subscription( subscription.id, - &mut **transaction, + &mut *transaction, ) .await? .ok_or_else(|| { @@ -2598,7 +2597,7 @@ pub async fn credit( server_ids.dedup(); let subs = user_subscription_item::DBUserSubscription::get_many_by_server_ids( &server_ids, - &mut *transaction, + &mut transaction, ) .await?; if subs.is_empty() { @@ -2622,7 +2621,7 @@ pub async fn credit( archon_client.get_active_servers_by_region(®ion).await?; let subs = user_subscription_item::DBUserSubscription::get_many_by_server_ids( &servers.into_iter().map(|id| id.to_string()).collect::>(), - &mut *transaction, + &mut transaction, ) .await?; if subs.is_empty() { diff --git a/apps/labrinth/src/routes/internal/billing/payments.rs b/apps/labrinth/src/routes/internal/billing/payments.rs index f30821f86..d150a417d 100644 --- a/apps/labrinth/src/routes/internal/billing/payments.rs +++ b/apps/labrinth/src/routes/internal/billing/payments.rs @@ -10,10 +10,10 @@ use crate::models::v3::users::User; use crate::routes::ApiError; use crate::util::anrok; +use crate::database::PgPool; use ariadne::ids::base62_impl::to_base62; use ariadne::ids::*; use serde::Deserialize; -use sqlx::PgPool; use std::collections::HashMap; use std::str::FromStr; use stripe::{ @@ -92,7 +92,7 @@ impl AttachedCharge { } pub async fn from_charge_request_type( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, charge_request_type: ChargeRequestType, ) -> Result { Ok(match charge_request_type { diff --git a/apps/labrinth/src/routes/internal/delphi.rs b/apps/labrinth/src/routes/internal/delphi.rs index 86989568e..8103a9194 100644 --- a/apps/labrinth/src/routes/internal/delphi.rs +++ b/apps/labrinth/src/routes/internal/delphi.rs @@ -1,11 +1,11 @@ use std::{collections::HashMap, fmt::Write, sync::LazyLock, time::Instant}; +use crate::database::PgPool; use actix_web::{HttpRequest, HttpResponse, get, post, web}; use chrono::{DateTime, Utc}; use eyre::eyre; use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT}; use serde::Deserialize; -use sqlx::PgPool; use tokio::sync::Mutex; use tracing::info; @@ -200,7 +200,7 @@ async fn ingest_report_deserialized( "#, DBProjectId::from(report.project_id) as _, ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await .wrap_internal_err("failed to check if pending issue details exist")?; @@ -292,7 +292,7 @@ async fn ingest_report_deserialized( } pub async fn run( - exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + exec: impl crate::database::Executor<'_, Database = sqlx::Postgres>, run_parameters: DelphiRunParameters, ) -> Result { let file_data = sqlx::query!( diff --git a/apps/labrinth/src/routes/internal/external_notifications.rs b/apps/labrinth/src/routes/internal/external_notifications.rs index a8e54c64a..def435071 100644 --- a/apps/labrinth/src/routes/internal/external_notifications.rs +++ b/apps/labrinth/src/routes/internal/external_notifications.rs @@ -1,4 +1,5 @@ use crate::auth::get_user_from_headers; +use crate::database::PgPool; use crate::database::models::ids::DBUserId; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::user_item::DBUser; @@ -14,7 +15,6 @@ use actix_web::web; use actix_web::{HttpResponse, post}; use ariadne::ids::UserId; use serde::Deserialize; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(create).service(send_custom_email); @@ -41,7 +41,7 @@ pub async fn create( let mut txn = pool.begin().await?; - if !DBUser::exists_many(&user_ids, &mut *txn).await? { + if !DBUser::exists_many(&user_ids, &mut txn).await? { return Err(ApiError::InvalidInput( "One of the specified users do not exist.".to_owned(), )); diff --git a/apps/labrinth/src/routes/internal/flows.rs b/apps/labrinth/src/routes/internal/flows.rs index bc02b05fe..84510685b 100644 --- a/apps/labrinth/src/routes/internal/flows.rs +++ b/apps/labrinth/src/routes/internal/flows.rs @@ -2,6 +2,8 @@ use crate::auth::validate::{ get_full_user_from_headers, get_user_record_from_bearer_token, }; use crate::auth::{AuthProvider, AuthenticationError, get_user_from_headers}; +use crate::database::PgPool; +use crate::database::PgTransaction; use crate::database::models::flow_item::DBFlow; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::{DBUser, DBUserId}; @@ -34,7 +36,6 @@ use rand_chacha::ChaCha20Rng; use rand_chacha::rand_core::SeedableRng; use reqwest::header::AUTHORIZATION; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgPool; use std::collections::HashMap; use std::str::FromStr; use std::sync::Arc; @@ -80,7 +81,7 @@ impl TempUser { async fn create_account( self, provider: AuthProvider, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, client: &PgPool, file_host: &Arc, redis: &RedisPool, @@ -834,7 +835,7 @@ impl AuthProvider { executor: E, ) -> Result, AuthenticationError> where - E: sqlx::Executor<'a, Database = sqlx::Postgres>, + E: crate::database::Executor<'a, Database = sqlx::Postgres>, { Ok(match self { AuthProvider::GitHub => { @@ -918,7 +919,7 @@ impl AuthProvider { &self, user_id: crate::database::models::DBUserId, id: Option<&str>, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), AuthenticationError> { match self { AuthProvider::GitHub => { @@ -931,7 +932,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id.and_then(|x| x.parse::().ok()) ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::Discord => { @@ -944,7 +945,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id.and_then(|x| x.parse::().ok()) ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::Microsoft => { @@ -957,7 +958,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::GitLab => { @@ -970,7 +971,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id.and_then(|x| x.parse::().ok()) ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::Google => { @@ -983,7 +984,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::Steam => { @@ -996,7 +997,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id.and_then(|x| x.parse::().ok()) ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } AuthProvider::PayPal => { @@ -1009,7 +1010,7 @@ impl AuthProvider { ", user_id as crate::database::models::DBUserId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } else { sqlx::query!( @@ -1021,7 +1022,7 @@ impl AuthProvider { user_id as crate::database::models::DBUserId, id, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; } } @@ -1217,7 +1218,7 @@ pub async fn auth_callback( oauth_user.id, existing_user_id as DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await .wrap_err("failed to update user PayPal info")?; @@ -1649,7 +1650,7 @@ async fn validate_2fa_code( user_id: crate::database::models::DBUserId, redis: &RedisPool, pool: &PgPool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result { let totp = totp_rs::TOTP::new( totp_rs::Algorithm::SHA1, @@ -1705,7 +1706,7 @@ async fn validate_2fa_code( user_id as crate::database::models::ids::DBUserId, code as i64, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; crate::database::models::DBUser::clear_caches( @@ -1867,7 +1868,7 @@ pub async fn finish_2fa_flow( secret, user_id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -1877,7 +1878,7 @@ pub async fn finish_2fa_flow( ", user_id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let mut codes = Vec::new(); @@ -1898,7 +1899,7 @@ pub async fn finish_2fa_flow( user_id as crate::database::models::ids::DBUserId, val as i64, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; codes.push(to_base62(val)); @@ -1986,7 +1987,7 @@ pub async fn remove_2fa( ", user.id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -1996,7 +1997,7 @@ pub async fn remove_2fa( ", user.id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; NotificationBuilder { @@ -2036,7 +2037,7 @@ pub async fn reset_password_begin( let user = match crate::database::models::DBUser::get_by_case_insensitive_email( &reset_password.username_or_email, - &mut *txn, + &mut txn, ) .await?[..] { @@ -2044,7 +2045,7 @@ pub async fn reset_password_begin( // Try finding by username or ID crate::database::models::DBUser::get( &reset_password.username_or_email, - &mut *txn, + &mut txn, &redis, ) .await? @@ -2053,7 +2054,7 @@ pub async fn reset_password_begin( // If there is only one user with the given email, ignoring case, // we can assume it's the user we want to reset the password for crate::database::models::DBUser::get_id( - user_id, &mut *txn, &redis, + user_id, &mut txn, &redis, ) .await? } @@ -2065,12 +2066,12 @@ pub async fn reset_password_begin( if let Some(user_id) = crate::database::models::DBUser::get_by_email( &reset_password.username_or_email, - &mut *txn, + &mut txn, ) .await? { crate::database::models::DBUser::get_id( - user_id, &mut *txn, &redis, + user_id, &mut txn, &redis, ) .await? } else { @@ -2232,7 +2233,7 @@ pub async fn change_password( update_password, user.id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; if let Some(flow) = &change_password.flow { @@ -2317,7 +2318,7 @@ pub async fn set_email( email_address.email, user.id.0 as i64, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; if let Some(user_email) = user.email.clone() { @@ -2473,7 +2474,7 @@ pub async fn verify_email( ", user.id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; DBFlow::remove(&email.flow, &redis).await?; diff --git a/apps/labrinth/src/routes/internal/gdpr.rs b/apps/labrinth/src/routes/internal/gdpr.rs index 790225191..d3afdd645 100644 --- a/apps/labrinth/src/routes/internal/gdpr.rs +++ b/apps/labrinth/src/routes/internal/gdpr.rs @@ -1,10 +1,10 @@ use crate::auth::get_user_from_headers; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::pats::Scopes; use crate::queue::session::AuthQueue; use crate::routes::ApiError; use actix_web::{HttpRequest, HttpResponse, post, web}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(web::scope("gdpr").service(export)); diff --git a/apps/labrinth/src/routes/internal/medal.rs b/apps/labrinth/src/routes/internal/medal.rs index 51018f2fd..196f43ba9 100644 --- a/apps/labrinth/src/routes/internal/medal.rs +++ b/apps/labrinth/src/routes/internal/medal.rs @@ -1,8 +1,8 @@ +use crate::database::PgPool; use actix_web::{HttpResponse, post, web}; use ariadne::ids::UserId; use chrono::Utc; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use tracing::warn; use crate::database::models::users_redeemals::{ @@ -63,7 +63,7 @@ pub async fn redeem( let maybe_fields = RedeemalLookupFields::redeemal_status_by_username_and_offer( - &mut *txn, + &mut txn, &username, Offer::Medal, ) @@ -93,7 +93,7 @@ pub async fn redeem( n_attempts: 0, }; - redeemal.insert(&mut *txn).await?; + redeemal.insert(&mut txn).await?; txn.commit().await?; diff --git a/apps/labrinth/src/routes/internal/moderation/mod.rs b/apps/labrinth/src/routes/internal/moderation/mod.rs index 972145325..a4e9d656d 100644 --- a/apps/labrinth/src/routes/internal/moderation/mod.rs +++ b/apps/labrinth/src/routes/internal/moderation/mod.rs @@ -1,6 +1,7 @@ use super::ApiError; use crate::auth::get_user_from_headers; use crate::database; +use crate::database::PgPool; use crate::database::models::DBModerationLock; use crate::database::redis::RedisPool; use crate::models::ids::OrganizationId; @@ -14,7 +15,6 @@ use ariadne::ids::{UserId, random_base62}; use chrono::{DateTime, Utc}; use ownership::get_projects_ownership; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::collections::HashMap; mod ownership; @@ -462,7 +462,7 @@ async fn set_project_meta( .bind(&links[..]) .bind(&proofs[..]) .bind(&flame_ids[..]) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query( @@ -475,7 +475,7 @@ async fn set_project_meta( ) .bind(&file_hashes[..]) .bind(&ids[..]) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/internal/moderation/ownership.rs b/apps/labrinth/src/routes/internal/moderation/ownership.rs index 5979811ce..5792ca6d1 100644 --- a/apps/labrinth/src/routes/internal/moderation/ownership.rs +++ b/apps/labrinth/src/routes/internal/moderation/ownership.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::{DBOrganization, DBTeamId, DBTeamMember, DBUser}; use crate::database::redis::RedisPool; use crate::models::ids::OrganizationId; @@ -5,7 +6,6 @@ use crate::routes::internal::moderation::Ownership; use crate::util::error::Context; use ariadne::ids::UserId; use eyre::eyre; -use sqlx::PgPool; /// Fetches ownership information for multiple projects efficiently pub async fn get_projects_ownership( diff --git a/apps/labrinth/src/routes/internal/moderation/tech_review.rs b/apps/labrinth/src/routes/internal/moderation/tech_review.rs index 3197f5ede..be0b960bb 100644 --- a/apps/labrinth/src/routes/internal/moderation/tech_review.rs +++ b/apps/labrinth/src/routes/internal/moderation/tech_review.rs @@ -1,10 +1,10 @@ use std::{collections::HashMap, fmt}; +use crate::database::PgPool; use actix_web::{HttpRequest, get, patch, post, put, web}; use chrono::{DateTime, Utc}; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use super::ownership::get_projects_ownership; use crate::{ @@ -986,7 +986,7 @@ async fn submit_report( "#, project_id as _, ) - .fetch_all(&mut *txn) + .fetch_all(&mut txn) .await .wrap_internal_err("failed to fetch pending issues")?; @@ -1016,7 +1016,7 @@ async fn submit_report( ", project_id as _, ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_internal_err("failed to delete dummy issue")?; @@ -1029,7 +1029,7 @@ async fn submit_report( "#, project_id as _, ) - .fetch_one(&mut *txn) + .fetch_one(&mut txn) .await .wrap_internal_err("failed to update reports")?; @@ -1087,7 +1087,7 @@ async fn submit_report( ProjectStatus::Rejected.as_str(), project_id as _, ) - .fetch_one(&mut *txn) + .fetch_one(&mut txn) .await .wrap_internal_err("failed to mark project as rejected")?; @@ -1182,7 +1182,7 @@ async fn update_issue_detail( status as _, issue_detail_id as _, ) - .execute(&mut *txn) + .execute(&mut txn) .await .wrap_internal_err("failed to update issue detail")?; if results.rows_affected() == 0 { @@ -1240,7 +1240,7 @@ async fn add_report( "#, DBFileId::from(file_id) as _, ) - .fetch_one(&mut *txn) + .fetch_one(&mut txn) .await .wrap_internal_err("failed to fetch file")?; diff --git a/apps/labrinth/src/routes/internal/pats.rs b/apps/labrinth/src/routes/internal/pats.rs index 7070c72b9..75d4ff37f 100644 --- a/apps/labrinth/src/routes/internal/pats.rs +++ b/apps/labrinth/src/routes/internal/pats.rs @@ -13,13 +13,13 @@ use rand::distributions::Alphanumeric; use rand_chacha::ChaCha20Rng; use rand_chacha::rand_core::SeedableRng; +use crate::database::PgPool; use crate::database::models::notification_item::NotificationBuilder; use crate::models::notifications::NotificationBody; use crate::models::pats::{PersonalAccessToken, Scopes}; use crate::queue::session::AuthQueue; use crate::util::validate::validation_errors_to_string; use serde::Deserialize; -use sqlx::postgres::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -216,7 +216,7 @@ pub async fn edit_pat( scopes.bits() as i64, pat.id.0 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } if let Some(name) = &info.name { @@ -229,7 +229,7 @@ pub async fn edit_pat( name, pat.id.0 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } if let Some(expires) = &info.expires { @@ -248,7 +248,7 @@ pub async fn edit_pat( expires, pat.id.0 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } diff --git a/apps/labrinth/src/routes/internal/session.rs b/apps/labrinth/src/routes/internal/session.rs index 1b20e3aee..d41cfd9ed 100644 --- a/apps/labrinth/src/routes/internal/session.rs +++ b/apps/labrinth/src/routes/internal/session.rs @@ -3,6 +3,7 @@ use crate::database::models::DBUserId; use crate::database::models::session_item::DBSession; use crate::database::models::session_item::SessionBuilder; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::models::pats::Scopes; use crate::models::sessions::Session; use crate::queue::session::AuthQueue; @@ -15,7 +16,6 @@ use chrono::Utc; use rand::distributions::Alphanumeric; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha20Rng; -use sqlx::PgPool; use woothee::parser::Parser; pub fn config(cfg: &mut ServiceConfig) { @@ -86,7 +86,7 @@ pub async fn get_session_metadata( pub async fn issue_session( req: HttpRequest, user_id: DBUserId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result { let metadata = get_session_metadata(&req).await?; @@ -112,7 +112,7 @@ pub async fn issue_session( .insert(transaction) .await?; - let session = DBSession::get_id(id, &mut **transaction, redis) + let session = DBSession::get_id(id, &mut *transaction, redis) .await? .ok_or_else(|| AuthenticationError::InvalidCredentials)?; diff --git a/apps/labrinth/src/routes/internal/statuses.rs b/apps/labrinth/src/routes/internal/statuses.rs index 416ea8053..f8196fec9 100644 --- a/apps/labrinth/src/routes/internal/statuses.rs +++ b/apps/labrinth/src/routes/internal/statuses.rs @@ -1,5 +1,6 @@ use crate::auth::AuthenticationError; use crate::auth::validate::get_user_record_from_bearer_token; +use crate::database::PgPool; use crate::database::models::friend_item::DBFriend; use crate::database::redis::RedisPool; use crate::models::pats::Scopes; @@ -27,7 +28,6 @@ use futures_util::future::select; use futures_util::{StreamExt, TryStreamExt}; use redis::AsyncCommands; use serde::Deserialize; -use sqlx::PgPool; use std::pin::pin; use std::sync::atomic::Ordering; use tokio::sync::oneshot::error::TryRecvError; diff --git a/apps/labrinth/src/routes/maven.rs b/apps/labrinth/src/routes/maven.rs index 510411523..109967a64 100644 --- a/apps/labrinth/src/routes/maven.rs +++ b/apps/labrinth/src/routes/maven.rs @@ -1,4 +1,5 @@ use crate::auth::checks::{is_visible_project, is_visible_version}; +use crate::database::PgPool; use crate::database::models::legacy_loader_fields::MinecraftGameVersion; use crate::database::models::loader_fields::Loader; use crate::database::models::project_item::ProjectQueryResult; @@ -12,7 +13,6 @@ use crate::queue::session::AuthQueue; use crate::routes::ApiError; use crate::{auth::get_user_from_headers, database}; use actix_web::{HttpRequest, HttpResponse, get, route, web}; -use sqlx::PgPool; use std::collections::HashSet; use yaserde::YaSerialize; diff --git a/apps/labrinth/src/routes/mod.rs b/apps/labrinth/src/routes/mod.rs index a8f9d08ce..9e845d7bb 100644 --- a/apps/labrinth/src/routes/mod.rs +++ b/apps/labrinth/src/routes/mod.rs @@ -105,11 +105,11 @@ pub enum ApiError { Env(#[from] dotenvy::Error), #[error("Error while uploading file: {0}")] FileHosting(#[from] FileHostingError), - #[error("Database error: {0}")] + #[error("database error")] Database(#[from] crate::database::models::DatabaseError), - #[error("SQLx database error: {0}")] + #[error("Postgres database error")] SqlxDatabase(#[from] sqlx::Error), - #[error("Redis database error: {0}")] + #[error("redis database error")] RedisDatabase(#[from] redis::RedisError), #[error("Clickhouse error: {0}")] Clickhouse(#[from] clickhouse::error::Error), @@ -125,7 +125,7 @@ pub enum ApiError { Validation(String), #[error("Search error: {0}")] Search(#[from] meilisearch_sdk::errors::Error), - #[error("Indexing error: {0}")] + #[error("search indexing error")] Indexing(#[from] crate::search::indexing::IndexingError), #[error("Payments error: {0}")] Payments(String), diff --git a/apps/labrinth/src/routes/updates.rs b/apps/labrinth/src/routes/updates.rs index 08fe83fbe..0478c706a 100644 --- a/apps/labrinth/src/routes/updates.rs +++ b/apps/labrinth/src/routes/updates.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; +use crate::database::PgPool; use actix_web::{HttpRequest, HttpResponse, get, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use crate::auth::checks::{filter_visible_versions, is_visible_project}; use crate::auth::get_user_from_headers; diff --git a/apps/labrinth/src/routes/v2/moderation.rs b/apps/labrinth/src/routes/v2/moderation.rs index f80970d15..37ec38c5d 100644 --- a/apps/labrinth/src/routes/v2/moderation.rs +++ b/apps/labrinth/src/routes/v2/moderation.rs @@ -1,4 +1,5 @@ use super::ApiError; +use crate::database::PgPool; use crate::models::projects::Project; use crate::models::v2::projects::LegacyProject; use crate::queue::session::AuthQueue; @@ -6,7 +7,6 @@ use crate::routes::internal; use crate::{database::redis::RedisPool, routes::v2_reroute}; use actix_web::{HttpRequest, HttpResponse, get, web}; use serde::Deserialize; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(web::scope("moderation").service(get_projects)); diff --git a/apps/labrinth/src/routes/v2/notifications.rs b/apps/labrinth/src/routes/v2/notifications.rs index 4cce65b49..a37d084d4 100644 --- a/apps/labrinth/src/routes/v2/notifications.rs +++ b/apps/labrinth/src/routes/v2/notifications.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::ids::NotificationId; use crate::models::notifications::Notification; @@ -8,7 +9,6 @@ use crate::routes::v2_reroute; use crate::routes::v3; use actix_web::{HttpRequest, HttpResponse, delete, get, patch, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(notifications_get); diff --git a/apps/labrinth/src/routes/v2/project_creation.rs b/apps/labrinth/src/routes/v2/project_creation.rs index 92514f8ff..543bb3487 100644 --- a/apps/labrinth/src/routes/v2/project_creation.rs +++ b/apps/labrinth/src/routes/v2/project_creation.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::version_item; use crate::database::redis::RedisPool; use crate::file_hosting::FileHost; @@ -16,7 +17,6 @@ use actix_web::web::Data; use actix_web::{HttpRequest, HttpResponse, post}; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::postgres::PgPool; use std::collections::HashMap; use std::sync::Arc; diff --git a/apps/labrinth/src/routes/v2/projects.rs b/apps/labrinth/src/routes/v2/projects.rs index 664148cc2..91c3f0b21 100644 --- a/apps/labrinth/src/routes/v2/projects.rs +++ b/apps/labrinth/src/routes/v2/projects.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::categories::LinkPlatform; use crate::database::models::{project_item, version_item}; use crate::database::redis::RedisPool; @@ -18,7 +19,6 @@ use crate::search::{ }; use actix_web::{HttpRequest, HttpResponse, delete, get, patch, post, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::collections::HashMap; use std::sync::Arc; use validator::Validate; diff --git a/apps/labrinth/src/routes/v2/reports.rs b/apps/labrinth/src/routes/v2/reports.rs index 8804c47a2..f77e7a635 100644 --- a/apps/labrinth/src/routes/v2/reports.rs +++ b/apps/labrinth/src/routes/v2/reports.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::reports::Report; use crate::models::v2::reports::LegacyReport; @@ -5,7 +6,6 @@ use crate::queue::session::AuthQueue; use crate::routes::{ApiError, v2_reroute, v3}; use actix_web::{HttpRequest, HttpResponse, delete, get, patch, post, web}; use serde::Deserialize; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { diff --git a/apps/labrinth/src/routes/v2/statistics.rs b/apps/labrinth/src/routes/v2/statistics.rs index 78bb9d626..cc034fe47 100644 --- a/apps/labrinth/src/routes/v2/statistics.rs +++ b/apps/labrinth/src/routes/v2/statistics.rs @@ -1,9 +1,9 @@ +use crate::database::PgPool; use crate::routes::{ ApiError, v2_reroute, v3::{self, statistics::V3Stats}, }; use actix_web::{HttpResponse, get, web}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(get_stats); diff --git a/apps/labrinth/src/routes/v2/tags.rs b/apps/labrinth/src/routes/v2/tags.rs index 1a9ae9a35..199196a5d 100644 --- a/apps/labrinth/src/routes/v2/tags.rs +++ b/apps/labrinth/src/routes/v2/tags.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::ApiError; +use crate::database::PgPool; use crate::database::models::loader_fields::LoaderFieldEnumValue; use crate::database::redis::RedisPool; use crate::models::v2::projects::LegacySideType; @@ -10,7 +11,6 @@ use crate::routes::{v2_reroute, v3}; use actix_web::{HttpResponse, get, web}; use chrono::{DateTime, Utc}; use itertools::Itertools; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( diff --git a/apps/labrinth/src/routes/v2/teams.rs b/apps/labrinth/src/routes/v2/teams.rs index 36d924ab2..5810f436c 100644 --- a/apps/labrinth/src/routes/v2/teams.rs +++ b/apps/labrinth/src/routes/v2/teams.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::ids::TeamId; use crate::models::teams::{ @@ -10,7 +11,6 @@ use actix_web::{HttpRequest, HttpResponse, delete, get, patch, post, web}; use ariadne::ids::UserId; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(teams_get); diff --git a/apps/labrinth/src/routes/v2/threads.rs b/apps/labrinth/src/routes/v2/threads.rs index 164de21ad..912ce4d60 100644 --- a/apps/labrinth/src/routes/v2/threads.rs +++ b/apps/labrinth/src/routes/v2/threads.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::file_hosting::FileHost; use crate::models::ids::{ThreadId, ThreadMessageId}; @@ -9,7 +10,6 @@ use crate::queue::session::AuthQueue; use crate::routes::{ApiError, v2_reroute, v3}; use actix_web::{HttpRequest, HttpResponse, delete, get, post, web}; use serde::Deserialize; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( diff --git a/apps/labrinth/src/routes/v2/users.rs b/apps/labrinth/src/routes/v2/users.rs index 952717eed..edf379b33 100644 --- a/apps/labrinth/src/routes/v2/users.rs +++ b/apps/labrinth/src/routes/v2/users.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::file_hosting::FileHost; use crate::models::notifications::Notification; @@ -10,7 +11,6 @@ use crate::queue::session::AuthQueue; use crate::routes::{ApiError, v2_reroute, v3}; use actix_web::{HttpRequest, HttpResponse, delete, get, patch, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::sync::Arc; use validator::Validate; diff --git a/apps/labrinth/src/routes/v2/version_creation.rs b/apps/labrinth/src/routes/v2/version_creation.rs index 0c27f200d..4fab4ccc6 100644 --- a/apps/labrinth/src/routes/v2/version_creation.rs +++ b/apps/labrinth/src/routes/v2/version_creation.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::loader_fields::VersionField; use crate::database::models::{project_item, version_item}; use crate::database::redis::RedisPool; @@ -18,7 +19,6 @@ use actix_web::web::Data; use actix_web::{HttpRequest, HttpResponse, post, web}; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::postgres::PgPool; use std::collections::HashMap; use std::sync::Arc; use validator::Validate; diff --git a/apps/labrinth/src/routes/v2/version_file.rs b/apps/labrinth/src/routes/v2/version_file.rs index b4a6cfebf..3c89eef0b 100644 --- a/apps/labrinth/src/routes/v2/version_file.rs +++ b/apps/labrinth/src/routes/v2/version_file.rs @@ -1,4 +1,5 @@ use super::ApiError; +use crate::database::PgPool; use crate::database::ReadOnlyPgPool; use crate::database::redis::RedisPool; use crate::models::projects::{Project, Version, VersionType}; @@ -8,7 +9,6 @@ use crate::routes::v3::version_file::HashQuery; use crate::routes::{v2_reroute, v3}; use actix_web::{HttpRequest, HttpResponse, delete, get, post, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::collections::HashMap; pub fn config(cfg: &mut web::ServiceConfig) { diff --git a/apps/labrinth/src/routes/v2/versions.rs b/apps/labrinth/src/routes/v2/versions.rs index 0219ec1db..708f35b72 100644 --- a/apps/labrinth/src/routes/v2/versions.rs +++ b/apps/labrinth/src/routes/v2/versions.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::ApiError; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models; use crate::models::ids::VersionId; @@ -13,7 +14,6 @@ use crate::routes::{v2_reroute, v3}; use crate::search::SearchConfig; use actix_web::{HttpRequest, HttpResponse, delete, get, patch, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { diff --git a/apps/labrinth/src/routes/v3/analytics_get.rs b/apps/labrinth/src/routes/v3/analytics_get.rs index e3beec551..e35193d5d 100644 --- a/apps/labrinth/src/routes/v3/analytics_get.rs +++ b/apps/labrinth/src/routes/v3/analytics_get.rs @@ -11,13 +11,13 @@ mod old; use std::num::NonZeroU64; +use crate::database::PgPool; use actix_web::{HttpRequest, post, web}; use chrono::{DateTime, TimeDelta, Utc}; use eyre::eyre; use futures::StreamExt; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use crate::{ auth::{AuthenticationError, get_user_from_headers}, diff --git a/apps/labrinth/src/routes/v3/analytics_get/old.rs b/apps/labrinth/src/routes/v3/analytics_get/old.rs index 79c5330c0..22e84cc2c 100644 --- a/apps/labrinth/src/routes/v3/analytics_get/old.rs +++ b/apps/labrinth/src/routes/v3/analytics_get/old.rs @@ -2,6 +2,7 @@ use super::ApiError; use crate::database; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::teams::ProjectPermissions; use crate::{ @@ -15,7 +16,6 @@ use ariadne::ids::base62_impl::to_base62; use chrono::{DateTime, Duration, Utc}; use eyre::eyre; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use sqlx::postgres::types::PgInterval; use std::collections::HashMap; use std::convert::TryInto; diff --git a/apps/labrinth/src/routes/v3/collections.rs b/apps/labrinth/src/routes/v3/collections.rs index 8967701af..5384348fa 100644 --- a/apps/labrinth/src/routes/v3/collections.rs +++ b/apps/labrinth/src/routes/v3/collections.rs @@ -1,5 +1,6 @@ use crate::auth::checks::is_visible_collection; use crate::auth::{filter_visible_collections, get_user_from_headers}; +use crate::database::PgPool; use crate::database::models::{ collection_item, generate_collection_id, project_item, }; @@ -24,7 +25,6 @@ use chrono::Utc; use eyre::eyre; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::sync::Arc; use validator::Validate; @@ -96,7 +96,7 @@ pub async fn collection_create( let initial_project_ids = project_item::DBProject::get_many( &collection_create_data.projects, - &mut *transaction, + &mut transaction, &redis, ) .await? @@ -274,7 +274,7 @@ pub async fn collection_edit( name.trim(), id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -288,7 +288,7 @@ pub async fn collection_edit( description.as_ref(), id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -311,7 +311,7 @@ pub async fn collection_edit( status.to_string(), id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -324,7 +324,7 @@ pub async fn collection_edit( ", collection_item.id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let collection_item_ids = new_project_ids @@ -352,7 +352,7 @@ pub async fn collection_edit( &collection_item_ids[..], &validated_project_ids[..], ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -363,7 +363,7 @@ pub async fn collection_edit( ", collection_item.id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -458,7 +458,7 @@ pub async fn collection_icon_edit( upload_result.color.map(|x| x as i32), collection_item.id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -517,7 +517,7 @@ pub async fn delete_collection_icon( ", collection_item.id as database::models::ids::DBCollectionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/friends.rs b/apps/labrinth/src/routes/v3/friends.rs index 5e99db83d..359b21c60 100644 --- a/apps/labrinth/src/routes/v3/friends.rs +++ b/apps/labrinth/src/routes/v3/friends.rs @@ -1,4 +1,5 @@ use crate::auth::get_user_from_headers; +use crate::database::PgPool; use crate::database::models::friend_item::DBFriend; use crate::database::models::{DBUser, DBUserId}; use crate::database::redis::RedisPool; @@ -15,7 +16,6 @@ use crate::sync::status::get_user_status; use actix_web::{HttpRequest, HttpResponse, delete, get, post, web}; use ariadne::networking::message::ServerToClientMessage; use chrono::Utc; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(add_friend); diff --git a/apps/labrinth/src/routes/v3/images.rs b/apps/labrinth/src/routes/v3/images.rs index 93669a1aa..efeb59a83 100644 --- a/apps/labrinth/src/routes/v3/images.rs +++ b/apps/labrinth/src/routes/v3/images.rs @@ -4,6 +4,7 @@ use super::threads::is_authorized_thread; use crate::auth::checks::{is_team_member_project, is_team_member_version}; use crate::auth::get_user_from_headers; use crate::database; +use crate::database::PgPool; use crate::database::models::{ project_item, report_item, thread_item, version_item, }; @@ -17,7 +18,6 @@ use crate::util::img::upload_image_optimized; use crate::util::routes::read_limited_from_payload; use actix_web::{HttpRequest, HttpResponse, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.route("image", web::post().to(images_add)); diff --git a/apps/labrinth/src/routes/v3/limits.rs b/apps/labrinth/src/routes/v3/limits.rs index 9c679892c..5dfbbef25 100644 --- a/apps/labrinth/src/routes/v3/limits.rs +++ b/apps/labrinth/src/routes/v3/limits.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::{ auth::get_user_from_headers, database::redis::RedisPool, @@ -6,7 +7,6 @@ use crate::{ routes::ApiError, }; use actix_web::{HttpRequest, web}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( diff --git a/apps/labrinth/src/routes/v3/notifications.rs b/apps/labrinth/src/routes/v3/notifications.rs index 57898a567..b04c83390 100644 --- a/apps/labrinth/src/routes/v3/notifications.rs +++ b/apps/labrinth/src/routes/v3/notifications.rs @@ -1,5 +1,6 @@ use crate::auth::get_user_from_headers; use crate::database; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::models::ids::NotificationId; use crate::models::notifications::Notification; @@ -8,7 +9,6 @@ use crate::queue::session::AuthQueue; use crate::routes::ApiError; use actix_web::{HttpRequest, HttpResponse, web}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.route("notifications", web::get().to(notifications_get)); diff --git a/apps/labrinth/src/routes/v3/oauth_clients.rs b/apps/labrinth/src/routes/v3/oauth_clients.rs index e738c7e52..adcb4e477 100644 --- a/apps/labrinth/src/routes/v3/oauth_clients.rs +++ b/apps/labrinth/src/routes/v3/oauth_clients.rs @@ -1,6 +1,7 @@ use std::{collections::HashSet, fmt::Display, sync::Arc}; use super::ApiError; +use crate::database::{PgPool, PgTransaction}; use crate::file_hosting::FileHostPublicity; use crate::models::ids::OAuthClientId; use crate::util::img::{delete_old_images, upload_image_optimized}; @@ -38,7 +39,6 @@ use itertools::Itertools; use rand::{Rng, SeedableRng, distributions::Alphanumeric}; use rand_chacha::ChaCha20Rng; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -325,7 +325,7 @@ pub async fn oauth_client_edit( let mut transaction = pool.begin().await?; updated_client - .update_editable_fields(&mut *transaction) + .update_editable_fields(&mut transaction) .await?; if let Some(redirects) = redirect_uris { @@ -410,7 +410,7 @@ pub async fn oauth_client_icon_edit( editable_client.raw_icon_url = Some(upload_result.raw_url); editable_client - .update_editable_fields(&mut *transaction) + .update_editable_fields(&mut transaction) .await?; transaction.commit().await?; @@ -461,7 +461,7 @@ pub async fn oauth_client_icon_delete( editable_client.raw_icon_url = None; editable_client - .update_editable_fields(&mut *transaction) + .update_editable_fields(&mut transaction) .await?; transaction.commit().await?; @@ -536,7 +536,7 @@ fn generate_oauth_client_secret() -> String { async fn create_redirect_uris( uri_strings: impl IntoIterator, client_id: DBOAuthClientId, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result, DatabaseError> { let mut redirect_uris = vec![]; for uri in uri_strings.into_iter() { @@ -554,7 +554,7 @@ async fn create_redirect_uris( async fn edit_redirects( redirects: Vec, existing_client: &DBOAuthClient, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), DatabaseError> { let updated_redirects: HashSet = redirects.into_iter().collect(); let original_redirects: HashSet = existing_client @@ -569,14 +569,14 @@ async fn edit_redirects( &mut *transaction, ) .await?; - DBOAuthClient::insert_redirect_uris(&redirects_to_add, &mut **transaction) + DBOAuthClient::insert_redirect_uris(&redirects_to_add, &mut *transaction) .await?; let mut redirects_to_remove = existing_client.redirect_uris.clone(); redirects_to_remove.retain(|r| !updated_redirects.contains(&r.uri)); DBOAuthClient::remove_redirect_uris( redirects_to_remove.iter().map(|r| r.id), - &mut **transaction, + &mut *transaction, ) .await?; diff --git a/apps/labrinth/src/routes/v3/organizations.rs b/apps/labrinth/src/routes/v3/organizations.rs index c6db53753..890c6a4e4 100644 --- a/apps/labrinth/src/routes/v3/organizations.rs +++ b/apps/labrinth/src/routes/v3/organizations.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use super::ApiError; use crate::auth::checks::is_visible_organization; use crate::auth::{filter_visible_projects, get_user_from_headers}; +use crate::database::PgPool; use crate::database::models::team_item::DBTeamMember; use crate::database::models::{ DBOrganization, generate_organization_id, team_item, @@ -25,7 +26,6 @@ use ariadne::ids::UserId; use futures::TryStreamExt; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -158,7 +158,7 @@ pub async fn organization_create( organization_strings.push(new_organization.slug.clone()); let results = DBOrganization::get_many( &organization_strings, - &mut *transaction, + &mut transaction, &redis, ) .await?; @@ -454,7 +454,7 @@ pub async fn organizations_edit( description, id as database::models::ids::DBOrganizationId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -474,7 +474,7 @@ pub async fn organizations_edit( name, id as database::models::ids::DBOrganizationId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -488,7 +488,7 @@ pub async fn organizations_edit( let existing = DBOrganization::get( &slug.to_lowercase(), - &mut *transaction, + &mut transaction, &redis, ) .await?; @@ -513,7 +513,7 @@ pub async fn organizations_edit( ", slug ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if results.exists.unwrap_or(true) { @@ -533,7 +533,7 @@ pub async fn organizations_edit( Some(slug), id as database::models::ids::DBOrganizationId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -640,7 +640,7 @@ pub async fn organization_delete( ", organization.id as database::models::ids::DBOrganizationId ) - .fetch(&mut *transaction) + .fetch(&mut transaction) .map_ok(|c| database::models::DBTeamId(c.id)) .try_collect::>() .await?; @@ -797,7 +797,7 @@ pub async fn organization_projects_add( organization.id as database::models::DBOrganizationId, project_item.inner.id as database::models::ids::DBProjectId ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; // The former owner is no longer an owner (as it is now 'owned' by the organization, 'given' to them) @@ -813,7 +813,7 @@ pub async fn organization_projects_add( ", organization.team_id as database::models::ids::DBTeamId ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; let organization_owner_user_id = database::models::ids::DBUserId(organization_owner_user_id.id); @@ -826,7 +826,7 @@ pub async fn organization_projects_add( project_item.inner.team_id as database::models::ids::DBTeamId, organization_owner_user_id as database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1004,7 +1004,7 @@ pub async fn organization_projects_remove( new_owner.id as database::models::ids::DBTeamMemberId, ProjectPermissions::all().bits() as i64 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -1015,7 +1015,7 @@ pub async fn organization_projects_remove( ", project_item.inner.id as database::models::ids::DBProjectId ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1144,7 +1144,7 @@ pub async fn organization_icon_edit( upload_result.color.map(|x| x as i32), organization_item.id as database::models::ids::DBOrganizationId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1227,7 +1227,7 @@ pub async fn delete_organization_icon( ", organization_item.id as database::models::ids::DBOrganizationId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/payouts.rs b/apps/labrinth/src/routes/v3/payouts.rs index 0ed13f2c6..37a0596da 100644 --- a/apps/labrinth/src/routes/v3/payouts.rs +++ b/apps/labrinth/src/routes/v3/payouts.rs @@ -1,5 +1,6 @@ use crate::auth::validate::get_user_record_from_bearer_token; use crate::auth::{AuthenticationError, get_user_from_headers}; +use crate::database::PgPool; use crate::database::models::DBUserId; use crate::database::models::{generate_payout_id, users_compliance}; use crate::database::redis::RedisPool; @@ -21,7 +22,6 @@ use reqwest::Method; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use sha2::Sha256; -use sqlx::PgPool; use std::collections::HashMap; use tokio_stream::StreamExt; use tracing::error; @@ -71,7 +71,7 @@ pub async fn post_compliance_form( let mut txn = pool.begin().await?; let maybe_compliance = - users_compliance::UserCompliance::get_by_user_id(&mut *txn, user_id) + users_compliance::UserCompliance::get_by_user_id(&mut txn, user_id) .await?; let mut compliance = match maybe_compliance { @@ -125,7 +125,7 @@ pub async fn post_compliance_form( compliance.form_type = Some(body.0.form_type); compliance.last_checked = Utc::now() - COMPLIANCE_CHECK_DEBOUNCE; - compliance.upsert_partial(&mut *txn).await?; + compliance.upsert_partial(&mut txn).await?; txn.commit().await?; Ok(HttpResponse::Ok().json(toplevel)) @@ -250,7 +250,7 @@ pub async fn paypal_webhook( webhook.resource.payout_item_id, PayoutStatus::InTransit.as_str() ) - .fetch_optional(&mut *transaction) + .fetch_optional(&mut transaction) .await?; if let Some(result) = result { @@ -268,7 +268,7 @@ pub async fn paypal_webhook( .as_str(), webhook.resource.payout_item_id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -294,7 +294,7 @@ pub async fn paypal_webhook( PayoutStatus::Success.as_str(), webhook.resource.payout_item_id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; } @@ -361,7 +361,7 @@ pub async fn tremendous_webhook( webhook.payload.resource.id, PayoutStatus::InTransit.as_str() ) - .fetch_optional(&mut *transaction) + .fetch_optional(&mut transaction) .await?; if let Some(result) = result { @@ -379,7 +379,7 @@ pub async fn tremendous_webhook( .as_str(), webhook.payload.resource.id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -405,7 +405,7 @@ pub async fn tremendous_webhook( PayoutStatus::Success.as_str(), webhook.payload.resource.id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; } @@ -491,7 +491,7 @@ pub async fn create_payout( ", user.id.0 ) - .fetch_optional(&mut *transaction) + .fetch_optional(&mut transaction) .await .wrap_internal_err("failed to fetch user balance")?; @@ -827,7 +827,7 @@ pub async fn cancel_payout( PayoutStatus::Cancelling.as_str(), platform_id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/project_creation.rs b/apps/labrinth/src/routes/v3/project_creation.rs index ac9328afc..c20619085 100644 --- a/apps/labrinth/src/routes/v3/project_creation.rs +++ b/apps/labrinth/src/routes/v3/project_creation.rs @@ -1,5 +1,7 @@ use super::version_creation::{InitialVersionData, try_create_version_fields}; use crate::auth::{AuthenticationError, get_user_from_headers}; +use crate::database::PgPool; +use crate::database::PgTransaction; use crate::database::models::loader_fields::{ Loader, LoaderField, LoaderFieldEnumValue, }; @@ -36,7 +38,6 @@ use image::ImageError; use itertools::Itertools; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgPool; use std::collections::HashMap; use std::sync::Arc; use thiserror::Error; @@ -405,7 +406,7 @@ Project Creation Steps: async fn project_create_inner( req: HttpRequest, payload: &mut Multipart, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, file_host: &dyn FileHost, uploaded_files: &mut Vec, pool: &PgPool, @@ -429,7 +430,7 @@ async fn project_create_inner( } let all_loaders = - models::loader_fields::Loader::list(&mut **transaction, redis).await?; + models::loader_fields::Loader::list(&mut *transaction, redis).await?; let project_create_data: ProjectCreateData; let mut versions; @@ -484,7 +485,7 @@ async fn project_create_inner( ", slug_project_id as models::ids::DBProjectId ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await .map_err(|e| CreateError::DatabaseError(e.into()))?; @@ -500,7 +501,7 @@ async fn project_create_inner( ", create_data.slug ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await .map_err(|e| CreateError::DatabaseError(e.into()))?; @@ -695,7 +696,7 @@ async fn project_create_inner( for category in &project_create_data.categories { let ids = models::categories::Category::get_ids( category, - &mut **transaction, + &mut *transaction, ) .await?; if ids.is_empty() { @@ -712,7 +713,7 @@ async fn project_create_inner( for category in &project_create_data.additional_categories { let ids = models::categories::Category::get_ids( category, - &mut **transaction, + &mut *transaction, ) .await?; if ids.is_empty() { @@ -798,12 +799,12 @@ async fn project_create_inner( let mut link_urls = vec![]; let link_platforms = - models::categories::LinkPlatform::list(&mut **transaction, redis) + models::categories::LinkPlatform::list(&mut *transaction, redis) .await?; for (platform, url) in &project_create_data.link_urls { let platform_id = models::categories::LinkPlatform::get_id( platform, - &mut **transaction, + &mut *transaction, ) .await? .ok_or_else(|| { @@ -875,7 +876,7 @@ async fn project_create_inner( for image_id in project_create_data.uploaded_images { if let Some(db_image) = image_item::DBImage::get( image_id.into(), - &mut **transaction, + &mut *transaction, redis, ) .await? @@ -898,7 +899,7 @@ async fn project_create_inner( id as models::ids::DBProjectId, image_id.0 as i64 ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; image_item::DBImage::clear_cache(image.id.into(), redis) @@ -925,7 +926,7 @@ async fn project_create_inner( .flat_map(|v| v.loaders.clone()) .unique() .collect::>(); - let (project_types, games) = Loader::list(&mut **transaction, redis) + let (project_types, games) = Loader::list(&mut *transaction, redis) .await? .into_iter() .fold( @@ -997,7 +998,7 @@ async fn create_initial_version( project_id: ProjectId, author: UserId, all_loaders: &[models::loader_fields::Loader], - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result { if version_data.project_id.is_some() { @@ -1027,11 +1028,11 @@ async fn create_initial_version( .collect::, CreateError>>()?; let loader_fields = - LoaderField::get_fields(&loaders, &mut **transaction, redis).await?; + LoaderField::get_fields(&loaders, &mut *transaction, redis).await?; let mut loader_field_enum_values = LoaderFieldEnumValue::list_many_loader_fields( &loader_fields, - &mut **transaction, + &mut *transaction, redis, ) .await?; diff --git a/apps/labrinth/src/routes/v3/projects.rs b/apps/labrinth/src/routes/v3/projects.rs index 4f0d981d1..ac6e362a0 100644 --- a/apps/labrinth/src/routes/v3/projects.rs +++ b/apps/labrinth/src/routes/v3/projects.rs @@ -11,6 +11,7 @@ use crate::database::models::{ }; use crate::database::redis::RedisPool; use crate::database::{self, models as db_models}; +use crate::database::{PgPool, PgTransaction}; use crate::file_hosting::{FileHost, FileHostPublicity}; use crate::models; use crate::models::ids::{ProjectId, VersionId}; @@ -40,7 +41,6 @@ use futures::TryStreamExt; use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -328,7 +328,7 @@ pub async fn project_edit( name.trim(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -349,7 +349,7 @@ pub async fn project_edit( summary, id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -404,7 +404,7 @@ pub async fn project_edit( ", id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; moderation_queue @@ -421,7 +421,7 @@ pub async fn project_edit( ", id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -447,7 +447,7 @@ pub async fn project_edit( ", id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -484,7 +484,7 @@ pub async fn project_edit( ", project_item.inner.team_id as db_ids::DBTeamId ) - .fetch(&mut *transaction) + .fetch(&mut transaction) .map_ok(|c| db_models::DBUserId(c.id)) .try_collect::>() .await?; @@ -537,7 +537,7 @@ pub async fn project_edit( status.as_str(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -567,7 +567,7 @@ pub async fn project_edit( requested_status.map(|x| x.as_str()), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -580,7 +580,7 @@ pub async fn project_edit( ", id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -592,7 +592,7 @@ pub async fn project_edit( ", id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } } @@ -636,7 +636,7 @@ pub async fn project_edit( license_url.as_deref(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -650,7 +650,7 @@ pub async fn project_edit( let existing = db_models::DBProject::get( &slug.to_lowercase(), - &mut *transaction, + &mut transaction, &redis, ) .await?; @@ -674,7 +674,7 @@ pub async fn project_edit( ", slug ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if results.exists.unwrap_or(true) { @@ -693,7 +693,7 @@ pub async fn project_edit( Some(slug), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -726,7 +726,7 @@ pub async fn project_edit( license, id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -752,14 +752,14 @@ pub async fn project_edit( id as db_ids::DBProjectId, &ids_to_delete ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; for (platform, url) in links { if let Some(url) = url { let platform_id = db_models::categories::LinkPlatform::get_id( platform, - &mut *transaction, + &mut transaction, ) .await? .ok_or_else(|| { @@ -777,7 +777,7 @@ pub async fn project_edit( platform_id as db_ids::LinkPlatformId, url ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } } @@ -802,7 +802,7 @@ pub async fn project_edit( moderation_message.as_deref(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -827,7 +827,7 @@ pub async fn project_edit( moderation_message_body.as_deref(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -848,7 +848,7 @@ pub async fn project_edit( description, id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -880,7 +880,7 @@ pub async fn project_edit( monetization_status.as_str(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -903,7 +903,7 @@ pub async fn project_edit( side_types_migration_review_status.as_str(), id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -993,7 +993,7 @@ pub async fn edit_project_categories( perms: &ProjectPermissions, project_id: db_ids::DBProjectId, is_additional: bool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), ApiError> { if !perms.contains(ProjectPermissions::EDIT_DETAILS) { let additional_str = if is_additional { "additional " } else { "" }; @@ -1006,7 +1006,7 @@ pub async fn edit_project_categories( for category in categories { let category_ids = db_models::categories::Category::get_ids( category, - &mut **transaction, + &mut *transaction, ) .await?; // TODO: We should filter out categories that don't match the project type of any of the versions @@ -1373,7 +1373,7 @@ pub async fn projects_edit( project.inner.id as db_ids::DBProjectId, &ids_to_delete ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; for (platform, url) in links { @@ -1397,7 +1397,7 @@ pub async fn projects_edit( platform_id as db_ids::LinkPlatformId, url ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } } @@ -1424,7 +1424,7 @@ pub async fn bulk_edit_project_categories( bulk_changes: CategoryChanges<'_>, max_num_categories: usize, is_additional: bool, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, ) -> Result<(), ApiError> { let mut set_categories = if let Some(categories) = bulk_changes.categories.clone() { @@ -1461,7 +1461,7 @@ pub async fn bulk_edit_project_categories( project_id as db_ids::DBProjectId, is_additional ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let mut mod_categories = Vec::new(); @@ -1594,7 +1594,7 @@ pub async fn project_icon_edit( upload_result.color.map(|x| x as i32), project_item.inner.id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1684,7 +1684,7 @@ pub async fn delete_project_icon( ", project_item.inner.id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -1823,7 +1823,7 @@ pub async fn add_gallery_item( project_item.inner.id as db_ids::DBProjectId, false, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -1969,7 +1969,7 @@ pub async fn edit_gallery_item( project_item.inner.id as db_ids::DBProjectId, false, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -1982,7 +1982,7 @@ pub async fn edit_gallery_item( result.id, featured ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } if let Some(name) = item.name { @@ -1995,7 +1995,7 @@ pub async fn edit_gallery_item( result.id, name ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } if let Some(description) = item.description { @@ -2008,7 +2008,7 @@ pub async fn edit_gallery_item( result.id, description ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } if let Some(ordering) = item.ordering { @@ -2021,7 +2021,7 @@ pub async fn edit_gallery_item( result.id, ordering ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -2137,7 +2137,7 @@ pub async fn delete_gallery_item( ", item.id ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -2228,7 +2228,7 @@ pub async fn project_delete( ", project.inner.id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let result = db_models::DBProject::remove( @@ -2313,7 +2313,7 @@ pub async fn project_follow( ", project_id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -2324,7 +2324,7 @@ pub async fn project_follow( user_id as db_ids::DBUserId, project_id as db_ids::DBProjectId ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; @@ -2389,7 +2389,7 @@ pub async fn project_unfollow( ", project_id as db_ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -2400,7 +2400,7 @@ pub async fn project_unfollow( user_id as db_ids::DBUserId, project_id as db_ids::DBProjectId ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/reports.rs b/apps/labrinth/src/routes/v3/reports.rs index 03346201c..e13f4ae57 100644 --- a/apps/labrinth/src/routes/v3/reports.rs +++ b/apps/labrinth/src/routes/v3/reports.rs @@ -1,5 +1,6 @@ use crate::auth::{check_is_moderator_from_headers, get_user_from_headers}; use crate::database; +use crate::database::PgPool; use crate::database::models::image_item; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::thread_item::{ @@ -22,7 +23,6 @@ use ariadne::ids::UserId; use ariadne::ids::base62_impl::parse_base62; use chrono::Utc; use serde::Deserialize; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -71,7 +71,7 @@ pub async fn report_create( crate::database::models::generate_report_id(&mut transaction).await?; let report_type = crate::database::models::categories::ReportType::get_id( &new_report.report_type, - &mut *transaction, + &mut transaction, ) .await? .ok_or_else(|| { @@ -102,7 +102,7 @@ pub async fn report_create( "SELECT EXISTS(SELECT 1 FROM mods WHERE id = $1)", project_id.0 as i64 ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if !result.exists.unwrap_or(false) { @@ -122,7 +122,7 @@ pub async fn report_create( "SELECT EXISTS(SELECT 1 FROM versions WHERE id = $1)", version_id.0 as i64 ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if !result.exists.unwrap_or(false) { @@ -141,7 +141,7 @@ pub async fn report_create( "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1)", user_id.0 as i64 ) - .fetch_one(&mut *transaction) + .fetch_one(&mut transaction) .await?; if !result.exists.unwrap_or(false) { @@ -165,7 +165,7 @@ pub async fn report_create( for image_id in new_report.uploaded_images { if let Some(db_image) = - image_item::DBImage::get(image_id.into(), &mut *transaction, &redis) + image_item::DBImage::get(image_id.into(), &mut transaction, &redis) .await? { let image: Image = db_image.into(); @@ -186,7 +186,7 @@ pub async fn report_create( id.0 as i64, image_id.0 as i64 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; image_item::DBImage::clear_cache(image.id.into(), &redis).await?; @@ -442,7 +442,7 @@ pub async fn report_edit( edit_body, id as crate::database::models::ids::DBReportId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -483,7 +483,7 @@ pub async fn report_edit( edit_closed, id as crate::database::models::ids::DBReportId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } diff --git a/apps/labrinth/src/routes/v3/shared_instance_version_creation.rs b/apps/labrinth/src/routes/v3/shared_instance_version_creation.rs index aaf35b6fb..657853c25 100644 --- a/apps/labrinth/src/routes/v3/shared_instance_version_creation.rs +++ b/apps/labrinth/src/routes/v3/shared_instance_version_creation.rs @@ -7,6 +7,7 @@ use crate::database::models::{ generate_shared_instance_version_id, }; use crate::database::redis::RedisPool; +use crate::database::{PgPool, PgTransaction}; use crate::file_hosting::{FileHost, FileHostPublicity}; use crate::models::ids::{SharedInstanceId, SharedInstanceVersionId}; use crate::models::pats::Scopes; @@ -24,7 +25,6 @@ use bytes::BytesMut; use chrono::Utc; use futures_util::StreamExt; use hex::FromHex; -use sqlx::{PgPool, Postgres, Transaction}; use std::sync::Arc; const MAX_FILE_SIZE: usize = 500 * 1024 * 1024; @@ -100,7 +100,7 @@ async fn shared_instance_version_create_inner( file_host: &dyn FileHost, instance_id: DBSharedInstanceId, session_queue: &AuthQueue, - transaction: &mut Transaction<'_, Postgres>, + transaction: &mut PgTransaction<'_>, uploaded_files: &mut Vec, ) -> Result { let user = get_user_from_headers( @@ -192,7 +192,7 @@ async fn shared_instance_version_create_inner( new_version.id as DBSharedInstanceVersionId, instance_id as DBSharedInstanceId, ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; let version: SharedInstanceVersion = new_version.into(); diff --git a/apps/labrinth/src/routes/v3/shared_instances.rs b/apps/labrinth/src/routes/v3/shared_instances.rs index fa1fc402e..260a0ef5e 100644 --- a/apps/labrinth/src/routes/v3/shared_instances.rs +++ b/apps/labrinth/src/routes/v3/shared_instances.rs @@ -1,5 +1,6 @@ use crate::auth::get_user_from_headers; use crate::auth::validate::get_maybe_user_from_headers; +use crate::database::PgPool; use crate::database::models::shared_instance_item::{ DBSharedInstance, DBSharedInstanceUser, DBSharedInstanceVersion, }; @@ -21,7 +22,6 @@ use actix_web::web::{Data, Redirect}; use actix_web::{HttpRequest, HttpResponse, web}; use futures_util::future::try_join_all; use serde::Deserialize; -use sqlx::PgPool; use std::sync::Arc; use validator::Validate; @@ -277,7 +277,7 @@ pub async fn shared_instance_edit( title, id as DBSharedInstanceId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -291,7 +291,7 @@ pub async fn shared_instance_edit( public, id as DBSharedInstanceId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -538,7 +538,7 @@ async fn delete_instance_version( ", version_id as DBSharedInstanceVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -554,7 +554,7 @@ async fn delete_instance_version( ", instance_id as DBSharedInstanceId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/statistics.rs b/apps/labrinth/src/routes/v3/statistics.rs index 169ff000c..a0f7141d9 100644 --- a/apps/labrinth/src/routes/v3/statistics.rs +++ b/apps/labrinth/src/routes/v3/statistics.rs @@ -1,6 +1,6 @@ +use crate::database::PgPool; use crate::routes::ApiError; use actix_web::{HttpResponse, web}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.route("statistics", web::get().to(get_stats)); diff --git a/apps/labrinth/src/routes/v3/tags.rs b/apps/labrinth/src/routes/v3/tags.rs index fff789891..a3ac589dc 100644 --- a/apps/labrinth/src/routes/v3/tags.rs +++ b/apps/labrinth/src/routes/v3/tags.rs @@ -10,9 +10,9 @@ use crate::database::models::loader_fields::{ use crate::database::redis::RedisPool; use actix_web::{HttpResponse, web}; +use crate::database::PgPool; use itertools::Itertools; use serde_json::Value; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( diff --git a/apps/labrinth/src/routes/v3/teams.rs b/apps/labrinth/src/routes/v3/teams.rs index 22d3d3fab..141965d16 100644 --- a/apps/labrinth/src/routes/v3/teams.rs +++ b/apps/labrinth/src/routes/v3/teams.rs @@ -1,6 +1,7 @@ use crate::auth::checks::{is_visible_organization, is_visible_project}; use crate::auth::get_user_from_headers; use crate::database::DBProject; +use crate::database::PgPool; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::team_item::TeamAssociationId; use crate::database::models::{DBOrganization, DBTeam, DBTeamMember, DBUser}; @@ -15,7 +16,6 @@ use actix_web::{HttpRequest, HttpResponse, web}; use ariadne::ids::UserId; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.route("teams", web::get().to(teams_get)); @@ -997,7 +997,7 @@ pub async fn transfer_ownership( ", oid.0 as i64 ) - .fetch_all(&mut *transaction) + .fetch_all(&mut transaction) .await?; let team_ids: Vec = diff --git a/apps/labrinth/src/routes/v3/threads.rs b/apps/labrinth/src/routes/v3/threads.rs index 852ecab21..fe38b5527 100644 --- a/apps/labrinth/src/routes/v3/threads.rs +++ b/apps/labrinth/src/routes/v3/threads.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use crate::auth::get_user_from_headers; use crate::database; +use crate::database::PgPool; use crate::database::models::image_item; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::thread_item::ThreadMessageBuilder; @@ -19,7 +20,6 @@ use crate::routes::ApiError; use actix_web::{HttpRequest, HttpResponse, web}; use futures::TryStreamExt; use serde::Deserialize; -use sqlx::PgPool; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( @@ -546,7 +546,7 @@ pub async fn thread_send_message_internal( for image_id in associated_images { if let Some(db_image) = image_item::DBImage::get( (*image_id).into(), - &mut *transaction, + &mut transaction, redis, ) .await? @@ -571,7 +571,7 @@ pub async fn thread_send_message_internal( thread.id.0, image_id.0 as i64 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; image_item::DBImage::clear_cache(image.id.into(), redis) diff --git a/apps/labrinth/src/routes/v3/users.rs b/apps/labrinth/src/routes/v3/users.rs index 67ffd8112..410e15ed0 100644 --- a/apps/labrinth/src/routes/v3/users.rs +++ b/apps/labrinth/src/routes/v3/users.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; use super::{ApiError, oauth_clients::get_user_clients}; +use crate::database::PgPool; use crate::{ auth::{ checks::is_visible_organization, filter_visible_collections, @@ -23,7 +24,6 @@ use crate::{ use actix_web::{HttpRequest, HttpResponse, web}; use ariadne::ids::UserId; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -422,7 +422,7 @@ pub async fn user_edit( username, id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } else { return Err(ApiError::InvalidInput(format!( @@ -441,7 +441,7 @@ pub async fn user_edit( bio.as_deref(), id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -464,7 +464,7 @@ pub async fn user_edit( role, id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -485,7 +485,7 @@ pub async fn user_edit( badges.bits() as i64, id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -506,7 +506,7 @@ pub async fn user_edit( venmo_handle, id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -520,7 +520,7 @@ pub async fn user_edit( allow_friend_requests, id as crate::database::models::ids::DBUserId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } diff --git a/apps/labrinth/src/routes/v3/version_creation.rs b/apps/labrinth/src/routes/v3/version_creation.rs index 69cbc8bcd..9b91a6bf8 100644 --- a/apps/labrinth/src/routes/v3/version_creation.rs +++ b/apps/labrinth/src/routes/v3/version_creation.rs @@ -1,5 +1,7 @@ use super::project_creation::{CreateError, UploadedFile}; use crate::auth::get_user_from_headers; +use crate::database::PgPool; +use crate::database::PgTransaction; use crate::database::models::loader_fields::{ LoaderField, LoaderFieldEnumValue, VersionField, }; @@ -35,7 +37,6 @@ use hex::ToHex; use itertools::Itertools; use serde::{Deserialize, Serialize}; use sha1::Digest; -use sqlx::postgres::PgPool; use std::collections::{HashMap, HashSet}; use std::sync::Arc; use validator::Validate; @@ -149,7 +150,7 @@ pub async fn version_create( async fn version_create_inner( req: HttpRequest, payload: &mut Multipart, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, file_host: &dyn FileHost, uploaded_files: &mut Vec, @@ -213,7 +214,7 @@ async fn version_create_inner( let project_id: models::DBProjectId = version_create_data.project_id.unwrap().into(); // Ensure that the project this version is being added to exists - if models::DBProject::get_id(project_id, &mut **transaction, redis) + if models::DBProject::get_id(project_id, &mut *transaction, redis) .await? .is_none() { @@ -228,14 +229,14 @@ async fn version_create_inner( project_id, user.id.into(), false, - &mut **transaction, + &mut *transaction, ) .await?; // Get organization attached, if exists, and the member project permissions let organization = models::DBOrganization::get_associated_organization_project_id( project_id, - &mut **transaction, + &mut *transaction, ) .await?; @@ -243,7 +244,7 @@ async fn version_create_inner( models::DBTeamMember::get_from_user_id( organization.team_id, user.id.into(), - &mut **transaction, + &mut *transaction, ) .await? } else { @@ -266,7 +267,7 @@ async fn version_create_inner( let version_id: VersionId = models::generate_version_id(transaction).await?.into(); let all_loaders = - models::loader_fields::Loader::list(&mut **transaction, redis).await?; + models::loader_fields::Loader::list(&mut *transaction, redis).await?; let loaders = version_create_data .loaders .iter() @@ -282,10 +283,10 @@ async fn version_create_inner( let loader_ids: Vec = loaders.iter().map(|y| y.id).collect_vec(); let loader_fields = - LoaderField::get_fields(&loader_ids, &mut **transaction, redis).await?; + LoaderField::get_fields(&loader_ids, &mut *transaction, redis).await?; let mut loader_field_enum_values = LoaderFieldEnumValue::list_many_loader_fields( &loader_fields, - &mut **transaction, + &mut *transaction, redis, ) .await?; @@ -402,7 +403,7 @@ async fn version_create_inner( ", builder.project_id as crate::database::models::ids::DBProjectId ) - .fetch(&mut **transaction) + .fetch(&mut *transaction) .map_ok(|m| models::ids::DBUserId(m.follower_id)) .try_collect::>() .await?; @@ -479,7 +480,7 @@ async fn version_create_inner( for image_id in version_data.uploaded_images { if let Some(db_image) = - image_item::DBImage::get(image_id.into(), &mut **transaction, redis) + image_item::DBImage::get(image_id.into(), &mut *transaction, redis) .await? { let image: Image = db_image.into(); @@ -500,7 +501,7 @@ async fn version_create_inner( version_id.0 as i64, image_id.0 as i64 ) - .execute(&mut **transaction) + .execute(&mut *transaction) .await?; image_item::DBImage::clear_cache(image.id.into(), redis).await?; @@ -580,7 +581,7 @@ async fn upload_file_to_version_inner( req: HttpRequest, payload: &mut Multipart, client: Data, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: Data, file_host: &dyn FileHost, uploaded_files: &mut Vec, @@ -609,7 +610,7 @@ async fn upload_file_to_version_inner( }; let all_loaders = - models::loader_fields::Loader::list(&mut **transaction, &redis).await?; + models::loader_fields::Loader::list(&mut *transaction, &redis).await?; let selected_loaders = version .loaders .iter() @@ -624,7 +625,7 @@ async fn upload_file_to_version_inner( if models::DBProject::get_id( version.inner.project_id, - &mut **transaction, + &mut *transaction, &redis, ) .await? @@ -640,7 +641,7 @@ async fn upload_file_to_version_inner( version.inner.project_id, user.id.into(), false, - &mut **transaction, + &mut *transaction, ) .await?; @@ -656,7 +657,7 @@ async fn upload_file_to_version_inner( models::DBTeamMember::get_from_user_id( organization.team_id, user.id.into(), - &mut **transaction, + &mut *transaction, ) .await? } else { @@ -798,7 +799,7 @@ pub async fn upload_file( force_primary: bool, file_type: Option, other_file_names: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result<(), CreateError> { let (file_name, file_extension) = get_name_ext(content_disposition)?; @@ -838,7 +839,7 @@ pub async fn upload_file( "sha1", project_id.0 as i64 ) - .fetch_one(&mut **transaction) + .fetch_one(&mut *transaction) .await? .exists .unwrap_or(false); @@ -883,7 +884,7 @@ pub async fn upload_file( ", &*hashes ) - .fetch_all(&mut **transaction) + .fetch_all(&mut *transaction) .await?; for file in &format.files { diff --git a/apps/labrinth/src/routes/v3/version_file.rs b/apps/labrinth/src/routes/v3/version_file.rs index bdf060ef1..b1865509a 100644 --- a/apps/labrinth/src/routes/v3/version_file.rs +++ b/apps/labrinth/src/routes/v3/version_file.rs @@ -1,6 +1,7 @@ use super::ApiError; use crate::auth::checks::{filter_visible_versions, is_visible_version}; use crate::auth::{filter_visible_projects, get_user_from_headers}; +use crate::database::PgPool; use crate::database::ReadOnlyPgPool; use crate::database::redis::RedisPool; use crate::models::ids::VersionId; @@ -14,7 +15,6 @@ use dashmap::DashMap; use futures::TryStreamExt; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use std::collections::HashMap; pub fn config(cfg: &mut web::ServiceConfig) { @@ -696,7 +696,7 @@ pub async fn delete_file( ", row.id.0 ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; sqlx::query!( @@ -706,7 +706,7 @@ pub async fn delete_file( ", row.id.0, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; transaction.commit().await?; diff --git a/apps/labrinth/src/routes/v3/versions.rs b/apps/labrinth/src/routes/v3/versions.rs index 4e906ed84..c58cb7eb4 100644 --- a/apps/labrinth/src/routes/v3/versions.rs +++ b/apps/labrinth/src/routes/v3/versions.rs @@ -6,6 +6,7 @@ use crate::auth::checks::{ }; use crate::auth::get_user_from_headers; use crate::database; +use crate::database::PgPool; use crate::database::models::loader_fields::{ self, LoaderField, LoaderFieldEnumValue, VersionField, }; @@ -32,7 +33,6 @@ use actix_web::{HttpRequest, HttpResponse, web}; use ariadne::ids::base62_impl::parse_base62; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use validator::Validate; pub fn config(cfg: &mut web::ServiceConfig) { @@ -361,7 +361,7 @@ pub async fn version_edit_helper( name.trim(), version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -375,7 +375,7 @@ pub async fn version_edit_helper( number, version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -389,7 +389,7 @@ pub async fn version_edit_helper( version_type.as_str(), version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -400,7 +400,7 @@ pub async fn version_edit_helper( ", version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let builders = dependencies @@ -429,7 +429,7 @@ pub async fn version_edit_helper( .collect::>(); let all_loaders = - loader_fields::Loader::list(&mut *transaction, &redis) + loader_fields::Loader::list(&mut transaction, &redis) .await?; let loader_ids = version_item .loaders @@ -444,7 +444,7 @@ pub async fn version_edit_helper( let loader_fields = LoaderField::get_fields( &loader_ids, - &mut *transaction, + &mut transaction, &redis, ) .await? @@ -465,13 +465,13 @@ pub async fn version_edit_helper( version_id as database::models::ids::DBVersionId, &loader_field_ids ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let mut loader_field_enum_values = LoaderFieldEnumValue::list_many_loader_fields( &loader_fields, - &mut *transaction, + &mut transaction, &redis, ) .await?; @@ -509,7 +509,7 @@ pub async fn version_edit_helper( ", version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let mut loader_versions = Vec::new(); @@ -517,7 +517,7 @@ pub async fn version_edit_helper( let loader_id = database::models::loader_fields::Loader::get_id( &loader.0, - &mut *transaction, + &mut transaction, &redis, ) .await? @@ -554,7 +554,7 @@ pub async fn version_edit_helper( featured, version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -568,7 +568,7 @@ pub async fn version_edit_helper( body, version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -588,7 +588,7 @@ pub async fn version_edit_helper( *downloads as i32, version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; let diff = *downloads - (version_item.inner.downloads as u32); @@ -603,7 +603,7 @@ pub async fn version_edit_helper( version_item.inner.project_id as database::models::ids::DBProjectId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -623,7 +623,7 @@ pub async fn version_edit_helper( status.as_str(), version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } @@ -656,7 +656,7 @@ pub async fn version_edit_helper( result.id, file_type.file_type.as_ref().map(|x| x.as_str()), ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } } @@ -671,7 +671,7 @@ pub async fn version_edit_helper( ordering.to_owned() as Option, version_id as database::models::ids::DBVersionId, ) - .execute(&mut *transaction) + .execute(&mut transaction) .await?; } diff --git a/apps/labrinth/src/search/indexing/local_import.rs b/apps/labrinth/src/search/indexing/local_import.rs index c19b1754d..6c2549fef 100644 --- a/apps/labrinth/src/search/indexing/local_import.rs +++ b/apps/labrinth/src/search/indexing/local_import.rs @@ -6,6 +6,7 @@ use std::collections::HashMap; use tracing::info; use super::IndexingError; +use crate::database::PgPool; use crate::database::models::loader_fields::{ QueryLoaderField, QueryLoaderFieldEnumValue, QueryVersionField, VersionField, @@ -18,7 +19,6 @@ use crate::models::projects::from_duplicate_version_fields; use crate::models::v2::projects::LegacyProject; use crate::routes::v2_reroute; use crate::search::UploadSearchProject; -use sqlx::postgres::PgPool; pub async fn index_local( pool: &PgPool, diff --git a/apps/labrinth/src/search/indexing/mod.rs b/apps/labrinth/src/search/indexing/mod.rs index 488ee7e8b..2b12e0ecc 100644 --- a/apps/labrinth/src/search/indexing/mod.rs +++ b/apps/labrinth/src/search/indexing/mod.rs @@ -3,6 +3,7 @@ pub mod local_import; use std::time::Duration; +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::search::{SearchConfig, UploadSearchProject}; use ariadne::ids::base62_impl::to_base62; @@ -13,7 +14,6 @@ use meilisearch_sdk::client::{Client, SwapIndexes}; use meilisearch_sdk::indexes::Index; use meilisearch_sdk::settings::{PaginationSetting, Settings}; use meilisearch_sdk::task_info::TaskInfo; -use sqlx::postgres::PgPool; use thiserror::Error; use tracing::{Instrument, error, info, info_span, instrument}; diff --git a/apps/labrinth/src/sync/friends.rs b/apps/labrinth/src/sync/friends.rs index 77f407da3..340e93216 100644 --- a/apps/labrinth/src/sync/friends.rs +++ b/apps/labrinth/src/sync/friends.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::queue::socket::ActiveSockets; use crate::routes::internal::statuses::{ broadcast_to_local_friends, send_message_to_user, @@ -9,7 +10,6 @@ use ariadne::users::UserStatus; use redis::aio::PubSub; use redis::{RedisWrite, ToRedisArgs}; use serde::{Deserialize, Serialize}; -use sqlx::PgPool; use tokio_stream::StreamExt; pub const FRIENDS_CHANNEL_NAME: &str = "friends"; diff --git a/apps/labrinth/src/test/database.rs b/apps/labrinth/src/test/database.rs index 9da2bda96..ea6df5570 100644 --- a/apps/labrinth/src/test/database.rs +++ b/apps/labrinth/src/test/database.rs @@ -1,7 +1,8 @@ +use crate::database::PgPool; use crate::database::redis::RedisPool; use crate::database::{MIGRATOR, ReadOnlyPgPool}; use crate::search; -use sqlx::{PgPool, postgres::PgPoolOptions}; +use sqlx::postgres::PgPoolOptions; use std::time::Duration; use url::Url; @@ -76,13 +77,14 @@ impl TemporaryDatabase { .connect(&temp_db_url) .await .expect("Connection to temporary database failed"); + let pool = PgPool::from(pool); let ro_pool = ReadOnlyPgPool::from(pool.clone()); println!("Running migrations on temporary database"); // Performs migrations - MIGRATOR.run(&pool).await.expect("Migrations failed"); + MIGRATOR.run(&*pool).await.expect("Migrations failed"); println!("Migrations complete"); @@ -110,8 +112,9 @@ impl TemporaryDatabase { // 6. Creates a temporary database at 'temp_database_name' from the template // 7. Drops lock and all created connections in the function async fn create_temporary(database_url: &str, temp_database_name: &str) { - let main_pool = PgPool::connect(database_url) + let main_pool = sqlx::PgPool::connect(database_url) .await + .map(PgPool::from) .expect("Connection to database failed"); loop { @@ -142,8 +145,9 @@ impl TemporaryDatabase { Url::parse(&url).expect("Invalid database URL"); template_url.set_path(&format!("/{TEMPLATE_DATABASE_NAME}")); - let pool = PgPool::connect(template_url.as_str()) + let pool = sqlx::PgPool::connect(template_url.as_str()) .await + .map(PgPool::from) .expect("Connection to database failed"); // Check if dummy data exists- a fake 'dummy_data' table is created if it does @@ -181,7 +185,7 @@ impl TemporaryDatabase { } // Run migrations on the template - MIGRATOR.run(&pool).await.expect("Migrations failed"); + MIGRATOR.run(&*pool).await.expect("Migrations failed"); if !dummy_data_exists { // Add dummy data @@ -234,8 +238,9 @@ impl TemporaryDatabase { dotenvy::var("DATABASE_URL").expect("No database URL"); self.pool.close().await; - self.pool = PgPool::connect(&database_url) + self.pool = sqlx::PgPool::connect(&database_url) .await + .map(PgPool::from) .expect("Connection to main database failed"); // Forcibly terminate all existing connections to this version of the temporary database @@ -259,7 +264,7 @@ impl TemporaryDatabase { } } -async fn create_template_database(pool: &sqlx::Pool) { +async fn create_template_database(pool: &PgPool) { let create_db_query = format!("CREATE DATABASE {TEMPLATE_DATABASE_NAME}"); sqlx::query(&create_db_query) .execute(pool) diff --git a/apps/labrinth/src/test/db.rs b/apps/labrinth/src/test/db.rs index cbfa24126..e50c710db 100644 --- a/apps/labrinth/src/test/db.rs +++ b/apps/labrinth/src/test/db.rs @@ -1,5 +1,7 @@ +use crate::database::Executor; use eyre::{Context, Result}; -use sqlx::{Executor, PgPool}; + +use crate::database::PgPool; /// Static personal access token for use in [`AppendPat`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/apps/labrinth/src/util/img.rs b/apps/labrinth/src/util/img.rs index 2c2488c82..1c5339e5e 100644 --- a/apps/labrinth/src/util/img.rs +++ b/apps/labrinth/src/util/img.rs @@ -1,6 +1,6 @@ -use crate::database; use crate::database::models::image_item; use crate::database::redis::RedisPool; +use crate::database::{self, PgTransaction}; use crate::file_hosting::{FileHost, FileHostPublicity}; use crate::models::images::ImageContext; use crate::routes::ApiError; @@ -202,7 +202,7 @@ pub async fn delete_old_images( pub async fn delete_unused_images( context: ImageContext, reference_strings: Vec<&str>, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result<(), ApiError> { let uploaded_images = diff --git a/apps/labrinth/src/util/webhook.rs b/apps/labrinth/src/util/webhook.rs index 7ae4e8a30..13d2970a0 100644 --- a/apps/labrinth/src/util/webhook.rs +++ b/apps/labrinth/src/util/webhook.rs @@ -1,3 +1,4 @@ +use crate::database::PgPool; use crate::database::models::legacy_loader_fields::MinecraftGameVersion; use crate::database::redis::RedisPool; use crate::models::ids::ProjectId; @@ -5,7 +6,6 @@ use crate::routes::ApiError; use ariadne::ids::base62_impl::to_base62; use chrono::{DateTime, Utc}; use serde::Serialize; -use sqlx::PgPool; const PLUGIN_LOADERS: &[&str] = &[ "bukkit", diff --git a/apps/labrinth/src/validate/mod.rs b/apps/labrinth/src/validate/mod.rs index 9d1d27b79..63a92dacb 100644 --- a/apps/labrinth/src/validate/mod.rs +++ b/apps/labrinth/src/validate/mod.rs @@ -1,3 +1,4 @@ +use crate::database::PgTransaction; use crate::database::models::DatabaseError; use crate::database::models::legacy_loader_fields::MinecraftGameVersion; use crate::database::models::loader_fields::VersionField; @@ -177,7 +178,7 @@ pub async fn validate_file( loaders: Vec, file_type: Option, version_fields: Vec, - transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + transaction: &mut PgTransaction<'_>, redis: &RedisPool, ) -> Result { let game_versions = version_fields diff --git a/packages/modrinth-log/Cargo.toml b/packages/modrinth-log/Cargo.toml index 962b7660f..eb8e53306 100644 --- a/packages/modrinth-log/Cargo.toml +++ b/packages/modrinth-log/Cargo.toml @@ -7,7 +7,7 @@ repository.workspace = true [dependencies] dotenvy = { workspace = true } eyre = { workspace = true } -sentry = { workspace = true, optional = true, features = ["tracing"] } +sentry = { workspace = true, features = ["tracing"], optional = true } tracing = { workspace = true } tracing-ecs = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/packages/modrinth-util/Cargo.toml b/packages/modrinth-util/Cargo.toml index 91c06d90f..6bd3992ec 100644 --- a/packages/modrinth-util/Cargo.toml +++ b/packages/modrinth-util/Cargo.toml @@ -19,8 +19,8 @@ serde_json = { workspace = true } [features] decimal = ["dep:rust_decimal", "utoipa?/decimal"] -utoipa = ["dep:utoipa"] sentry = ["modrinth-log/sentry"] +utoipa = ["dep:utoipa"] [lints] workspace = true diff --git a/packages/sqlx-tracing/.github/workflows/main.yml b/packages/sqlx-tracing/.github/workflows/main.yml new file mode 100644 index 000000000..e15cc0bb2 --- /dev/null +++ b/packages/sqlx-tracing/.github/workflows/main.yml @@ -0,0 +1,57 @@ +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + RUSTFLAGS: '-Dwarnings' + +name: check +jobs: + fmt: + runs-on: ubuntu-latest + name: fmt + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: cargo fmt --check --all + run: cargo fmt --check --all + + clippy: + runs-on: ubuntu-latest + name: clippy + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - run: cargo clippy --all-features --all-targets --tests + + test: + runs-on: ubuntu-latest + name: test + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + - run: cargo test --workspace --all-features + + features: + runs-on: ubuntu-latest + name: features + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + - uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + - name: features powerset + run: cargo hack check --feature-powerset --tests diff --git a/packages/sqlx-tracing/.github/workflows/release-pr.yml b/packages/sqlx-tracing/.github/workflows/release-pr.yml new file mode 100644 index 000000000..4a693587a --- /dev/null +++ b/packages/sqlx-tracing/.github/workflows/release-pr.yml @@ -0,0 +1,26 @@ +name: release-plz + +permissions: + pull-requests: write + contents: write + id-token: write + +on: + push: + branches: + - main + +jobs: + release-plz: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + id: release-plz + uses: MarcoIeni/release-plz-action@v0.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/packages/sqlx-tracing/.gitignore b/packages/sqlx-tracing/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/packages/sqlx-tracing/.gitignore @@ -0,0 +1 @@ +/target diff --git a/packages/sqlx-tracing/CHANGELOG.md b/packages/sqlx-tracing/CHANGELOG.md new file mode 100644 index 000000000..39575061a --- /dev/null +++ b/packages/sqlx-tracing/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.2.0](https://github.com/jdrouet/sqlx-tracing/compare/v0.1.0...v0.2.0) - 2025-10-02 + +### Added + +- add attributes to pool +- make sure returned_rows is populated +- trace on pool connections and transactions +- make it work with PoolConnection +- make transaction part compile +- create pool-connection and transaction + +### Fixed + +- unused import +- create separate builder for sqlite and postgres +- please clippy +- remove unused traits + +### Other + +- use opentelemetry-testing from registry +- comment the code +- update readme with pool builder +- ensure pool queries are traced +- release v0.1.0 + +## [0.1.0](https://github.com/jdrouet/sqlx-tracing/releases/tag/v0.1.0) - 2025-09-07 + +### Other + +- configure for auto release +- update cargo.toml +- set versions in dev deps +- add readme +- configure +- check that it works for sqlite and postgres +- simple project diff --git a/packages/sqlx-tracing/Cargo.lock b/packages/sqlx-tracing/Cargo.lock new file mode 100644 index 000000000..5784858e1 --- /dev/null +++ b/packages/sqlx-tracing/Cargo.lock @@ -0,0 +1,3706 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "axum" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +dependencies = [ + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bollard" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899ca34eb6924d6ec2a77c6f7f5c7339e60fd68235eaf91edd5a15f12958bb06" +dependencies = [ + "async-stream", + "base64 0.22.1", + "bitflags 2.9.4", + "bollard-buildkit-proto", + "bollard-stubs", + "bytes", + "chrono", + "futures-core", + "futures-util", + "hex", + "home", + "http", + "http-body-util", + "hyper", + "hyper-named-pipe", + "hyper-rustls", + "hyper-util", + "hyperlocal", + "log", + "num", + "pin-project-lite", + "rand 0.9.2", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tonic", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-buildkit-proto" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b3e79f8bd0f25f32660e3402afca46fd91bebaf135af017326d905651f8107" +dependencies = [ + "prost", + "prost-types", + "tonic", + "ureq", +] + +[[package]] +name = "bollard-stubs" +version = "1.48.3-rc.28.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ea257e555d16a2c01e5593f40b73865cdf12efbceda33c6d14a2d8d1490368" +dependencies = [ + "base64 0.22.1", + "bollard-buildkit-proto", + "bytes", + "chrono", + "prost", + "serde", + "serde_json", + "serde_repr", + "serde_with", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "docker_credential" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d89dfcba45b4afad7450a99b39e751590463e45c04728cf555d36bb66940de8" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[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 = "etcetera" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.59.0", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "filetime" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.60.2", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.3+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.11.0", + "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.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.0", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "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", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", + "serde", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +dependencies = [ + "bitflags 2.9.4", + "libc", + "redox_syscall 0.5.17", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "opentelemetry" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror", + "tracing", +] + +[[package]] +name = "opentelemetry-appender-tracing" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68f63eca5fad47e570e00e893094fc17be959c80c79a7d6ec1abdd5ae6ffc16" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry-http" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" +dependencies = [ + "http", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "reqwest", + "thiserror", + "tokio", + "tonic", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2" + +[[package]] +name = "opentelemetry-testing" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562407eb254fea88076c8a410a733a8ee2075fd9c7fbde3da2a03d29e2cef104" +dependencies = [ + "anyhow", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "serde", + "serde_json", + "serial_test", + "tempfile", + "testcontainers", + "tokio", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "rand 0.9.2", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.17", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "parse-display" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" +dependencies = [ + "parse-display-derive", + "regex", + "regex-syntax", +] + +[[package]] +name = "parse-display-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "regex-syntax", + "structmeta", + "syn", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags 2.9.4", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + +[[package]] +name = "security-framework" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +dependencies = [ + "bitflags 2.9.4", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.11.0", + "schemars 0.9.0", + "schemars 1.0.4", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64 0.22.1", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink", + "indexmap 2.11.0", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.9.4", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.9.4", + "byteorder", + "crc", + "dotenvy", + "etcetera 0.8.0", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror", + "tracing", + "url", +] + +[[package]] +name = "sqlx-tracing" +version = "0.2.0" +dependencies = [ + "anyhow", + "futures", + "opentelemetry", + "opentelemetry-testing", + "serde", + "serde_json", + "serial_test", + "sqlx", + "testcontainers", + "tokio", + "tracing", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "structmeta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn", +] + +[[package]] +name = "structmeta-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tempfile" +version = "3.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.60.2", +] + +[[package]] +name = "testcontainers" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b92bce247dc9260a19808321e11b51ea6a0293d02b48ab1c6578960610cfa2a7" +dependencies = [ + "async-trait", + "bollard", + "bollard-stubs", + "bytes", + "docker_credential", + "either", + "etcetera 0.10.0", + "futures", + "log", + "memchr", + "parse-display", + "pin-project-lite", + "serde", + "serde_json", + "serde_with", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tar", + "tokio-util", + "ulid", + "url", +] + +[[package]] +name = "thiserror" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2 0.6.0", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tar" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5714c010ca3e5c27114c1cdeb9d14641ace49874aa5626d7149e47aedace75" +dependencies = [ + "filetime", + "futures-core", + "libc", + "redox_syscall 0.3.5", + "tokio", + "tokio-stream", + "xattr", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2 0.5.10", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 2.11.0", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.4", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ulid" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" +dependencies = [ + "rand 0.9.2", + "web-time", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64 0.22.1", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots 0.26.11", +] + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.3+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +dependencies = [ + "wit-bindgen", +] + +[[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.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "xattr" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +dependencies = [ + "libc", + "rustix", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/packages/sqlx-tracing/Cargo.toml b/packages/sqlx-tracing/Cargo.toml new file mode 100644 index 000000000..bf89e32aa --- /dev/null +++ b/packages/sqlx-tracing/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "sqlx-tracing" +version = "0.2.0" +edition = "2024" +description = "OpenTelemetry-compatible tracing for SQLx database operations in Rust." +documentation = "https://docs.rs/sqlx-tracing" +readme = "README.md" +homepage = "https://github.com/jdrouet/sqlx-tracing" +repository = "https://github.com/jdrouet/sqlx-tracing" +license = "MIT" +# authors = ["Jérémie Drouet "] # deprecated field, Tombi warns +keywords = ["database", "observability", "opentelemetry", "sqlx", "tracing"] +categories = [ + "asynchronous", + "database", + "development-tools::debugging", + "development-tools::profiling" +] + +[dependencies] +derive_more = { workspace = true, features = ["deref", "deref_mut"] } +futures = { version = "0.3" } +sqlx = { version = "0.8", default-features = false, features = ["derive"] } +tracing = { version = "0.1" } + +[dev-dependencies] +opentelemetry = "0.30" +opentelemetry-testing = "0.1" +sqlx = { version = "0.8", features = ["runtime-tokio"] } +testcontainers = "0.25" +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } + +[features] +postgres = ["sqlx/postgres"] +sqlite = ["sqlx/sqlite"] diff --git a/packages/sqlx-tracing/README.md b/packages/sqlx-tracing/README.md new file mode 100644 index 000000000..fda11ad92 --- /dev/null +++ b/packages/sqlx-tracing/README.md @@ -0,0 +1,91 @@ +> [!NOTE] +> +> This is a vendored version of [`sqlx-tracing`](https://github.com/jdrouet/sqlx-tracing/) with modifications for our own purposes. +> +> This directory is licensed under the same license as the original project. + +# sqlx-tracing + +**sqlx-tracing** is a Rust library that provides OpenTelemetry-compatible tracing for SQLx database operations. It wraps SQLx connection pools and queries with tracing spans, enabling detailed observability of database interactions in distributed systems. + +## Features + +- **Automatic Tracing**: All SQLx queries executed through the provided pool are traced using [tracing](https://docs.rs/tracing) spans. +- **OpenTelemetry Integration**: Traces are compatible with OpenTelemetry, making it easy to export to collectors and observability platforms. +- **Error Recording**: Errors are automatically annotated with kind, message, and stacktrace in the tracing span. +- **Returned Rows**: The number of rows returned by queries is recorded for observability. +- **Database Agnostic**: Supports both PostgreSQL and SQLite via feature flags. +- **Macros**: Includes a macro for consistent span creation around queries. + +## Usage + +Add `sqlx-tracing` to your `Cargo.toml`: + +```toml +[dependencies] +sqlx-tracing = "0.1" +sqlx = { version = "0.8", default-features = false, features = ["derive"] } +tracing = "0.1" +``` + +Enable the desired database feature: + +- For PostgreSQL: `features = ["postgres"]` +- For SQLite: `features = ["sqlite"]` + +Wrap your SQLx pool: + +```rust,ignore +let pool = sqlx::PgPool::connect(&url).await?; +// the attributes will be resolved from the url +let traced_pool = sqlx_tracing::Pool::from(pool); +// or manually overwrite them +let traced_pool = sqlx_tracing::PoolBuilder::from(pool) + .with_name("my-domain-database") + .with_database("database") + .with_host("somewhere") + .with_port(1234) + .build(); +``` + +Use the traced pool as you would a normal SQLx pool: + +```rust,ignore +let result: Option = sqlx::query_scalar("select 1") + .fetch_optional(traced_pool) + .await?; +``` + +This works also with pool connections + +```rust,ignore +let mut conn = traced_pool.acquire().await?; +let result: Option = sqlx::query_scalar("select 1") + .fetch_optional(&mut conn) + .await?; +``` + +And transactions + +```rust,ignore +let mut tx = traced_pool.begin().await?; +let result: Option = sqlx::query_scalar("select 1") + .fetch_optional(&mut tx.executor()) + .await?; +``` + +## OpenTelemetry Integration + +To export traces, set up an OpenTelemetry collector and configure the tracing subscriber with the appropriate layers. See the `tests/common.rs` for a full example using `opentelemetry`, `opentelemetry-otlp`, and `tracing-opentelemetry`. + +## Testing + +Integration tests are provided for both PostgreSQL and SQLite, using [testcontainers](https://docs.rs/testcontainers) and a local OpenTelemetry collector. + +## License + +Licensed under MIT. + +## Contributing + +Contributions and issues are welcome! Please open a PR or issue on GitHub. diff --git a/packages/sqlx-tracing/src/any_connection.rs b/packages/sqlx-tracing/src/any_connection.rs new file mode 100644 index 000000000..d7cf3aa22 --- /dev/null +++ b/packages/sqlx-tracing/src/any_connection.rs @@ -0,0 +1,103 @@ +use crate::{AnyConnection, Database}; + +impl<'c, 's, DB> sqlx::Executor<'s> for &'s mut AnyConnection<'c, DB> +where + DB: Database, + // I attempted to have `DB::ConnectionRef<'c>` unify to `&'c mut DB::Connection`. + // This *can* be unified apparently, but we can't actually use the fact that + // `DB::ConnectionRef<'c>: sqlx::Executor` if we do this. + // So, we need a casting function in `crate::Database`. + // Maybe this can be revisited sometime to not require the casting fn. + // + // for<'a> DB: Database = &'a mut ::Connection>, +{ + type Database = DB; + + fn fetch_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result< + sqlx::Either< + ::QueryResult, + ::Row, + >, + sqlx::Error, + >, + > + where + 's: 'e, + E: 'q + sqlx::Execute<'q, Self::Database>, + { + match self { + AnyConnection::Pool(pool) => { + DB::cast_connection(&mut pool.inner).fetch_many(query) + } + AnyConnection::Raw(conn) => { + DB::cast_connection(conn.inner).fetch_many(query) + } + } + } + + fn fetch_optional<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + 's: 'e, + E: 'q + sqlx::Execute<'q, Self::Database>, + { + match self { + AnyConnection::Pool(pool) => { + DB::cast_connection(&mut pool.inner).fetch_optional(query) + } + AnyConnection::Raw(conn) => { + DB::cast_connection(conn.inner).fetch_optional(query) + } + } + } + + fn prepare_with<'e, 'q: 'e>( + self, + sql: &'q str, + parameters: &'e [::TypeInfo], + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 's: 'e, + { + match self { + AnyConnection::Pool(pool) => DB::cast_connection(&mut pool.inner) + .prepare_with(sql, parameters), + AnyConnection::Raw(conn) => { + DB::cast_connection(conn.inner).prepare_with(sql, parameters) + } + } + } + + fn describe<'e, 'q: 'e>( + self, + sql: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result, sqlx::Error>, + > + where + 's: 'e, + { + match self { + AnyConnection::Pool(pool) => { + DB::cast_connection(&mut pool.inner).describe(sql) + } + AnyConnection::Raw(conn) => { + DB::cast_connection(conn.inner).describe(sql) + } + } + } +} diff --git a/packages/sqlx-tracing/src/connection.rs b/packages/sqlx-tracing/src/connection.rs new file mode 100644 index 000000000..bab36bcd8 --- /dev/null +++ b/packages/sqlx-tracing/src/connection.rs @@ -0,0 +1,512 @@ +use futures::{StreamExt, TryStreamExt}; +use tracing::Instrument; + +impl AsMut<::Connection> for crate::PoolConnection +where + DB: crate::Database, +{ + fn as_mut(&mut self) -> &mut ::Connection { + self.inner.as_mut() + } +} + +impl<'c, DB> sqlx::Executor<'c> for &'c mut crate::PoolConnection +where + DB: crate::Database, + // impl<'a> Executor<'a> for PgConnection + for<'a> &'a mut DB::Connection: sqlx::Executor<'a, Database = DB>, +{ + type Database = DB; + + #[doc(hidden)] + fn describe<'e, 'q: 'e>( + self, + sql: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.describe", attrs, sql); + let fut = self.inner.as_mut().describe(sql); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute", attrs, sql); + let fut = self.inner.execute(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute_many", attrs, sql); + let stream = self.inner.execute_many(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch", attrs, sql); + let stream = self.inner.fetch(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_all<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let fut = self.inner.fetch_all(query); + Box::pin( + async move { + fut.await + .inspect(|res| { + let span = tracing::Span::current(); + span.record("db.response.returned_rows", res.len()); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result< + sqlx::Either< + ::QueryResult, + ::Row, + >, + sqlx::Error, + >, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let stream = self.inner.fetch_many(query); + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_one<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_one", attrs, sql); + let fut = self.inner.fetch_one(query); + Box::pin( + async move { + fut.await + .inspect(|_| { + tracing::Span::current() + .record("db.response.returned_rows", 1); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_optional<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_optional", attrs, sql); + let fut = self.inner.fetch_optional(query); + Box::pin( + async move { + fut.await + .inspect(|res| { + tracing::Span::current().record( + "db.response.returned_rows", + if res.is_some() { 1 } else { 0 }, + ); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn prepare<'e, 'q: 'e>( + self, + query: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare", attrs, query); + let fut = self.inner.prepare(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn prepare_with<'e, 'q: 'e>( + self, + sql: &'q str, + parameters: &'e [::TypeInfo], + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare_with", attrs, sql); + let fut = self.inner.prepare_with(sql, parameters); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } +} + +impl<'c, DB> sqlx::Executor<'c> for &'c mut crate::Connection<'c, DB> +where + DB: crate::Database, + for<'a> &'a mut DB::Connection: sqlx::Executor<'a, Database = DB>, +{ + type Database = DB; + + #[doc(hidden)] + fn describe<'e, 'q: 'e>( + self, + sql: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.describe", attrs, sql); + let fut = self.inner.describe(sql); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute", attrs, sql); + let fut = self.inner.execute(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute_many", attrs, sql); + let stream = self.inner.execute_many(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch", attrs, sql); + let stream = self.inner.fetch(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_all<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let fut = self.inner.fetch_all(query); + Box::pin( + async move { + fut.await + .inspect(|res| { + let span = tracing::Span::current(); + span.record("db.response.returned_rows", res.len()); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result< + sqlx::Either< + ::QueryResult, + ::Row, + >, + sqlx::Error, + >, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let stream = self.inner.fetch_many(query); + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_one<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_one", attrs, sql); + let fut = self.inner.fetch_one(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_one) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_optional<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 'c: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_optional", attrs, sql); + let fut = self.inner.fetch_optional(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_optional) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn prepare<'e, 'q: 'e>( + self, + query: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare", attrs, query); + let fut = self.inner.prepare(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn prepare_with<'e, 'q: 'e>( + self, + sql: &'q str, + parameters: &'e [::TypeInfo], + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 'c: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare_with", attrs, sql); + let fut = self.inner.prepare_with(sql, parameters); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } +} diff --git a/packages/sqlx-tracing/src/lib.rs b/packages/sqlx-tracing/src/lib.rs new file mode 100644 index 000000000..a9935249c --- /dev/null +++ b/packages/sqlx-tracing/src/lib.rs @@ -0,0 +1,219 @@ +#![doc = include_str!("../README.md")] + +use std::sync::Arc; + +use derive_more::{Deref, DerefMut}; +use futures::future::BoxFuture; + +mod any_connection; +mod connection; +mod pool; +pub(crate) mod span; +mod transaction; + +pub use sqlx::Executor; + +#[cfg(feature = "postgres")] +pub mod postgres; + +#[cfg(feature = "sqlite")] +pub mod sqlite; + +/// Attributes describing the database connection and context. +/// Used for span enrichment and attribute propagation. +#[derive(Debug, Default)] +struct Attributes { + name: Option, + host: Option, + port: Option, + database: Option, +} + +pub trait Database: sqlx::Database { + const SYSTEM: &'static str; + + /// Defines the type of reference to a database connection, equivalent to + /// `&'c mut ::Connection`. + /// + /// But we can't actually use the `sqlx::Database` named connection type, + /// since we can't statically prove that it implements `sqlx::Executor`. + /// Even if we unify the two types (see `any_connection.rs`), we can't use + /// connection refs as an executor. So we need this intermediate associated + /// type. + type ConnectionRef<'c>: sqlx::Executor<'c, Database = Self>; + + /// Casts a `&'c mut Self::Connection` to a `Self::ConnectionRef<'c>`. + /// + /// This should just return `conn`. + fn cast_connection<'c>( + conn: &'c mut ::Connection, + ) -> Self::ConnectionRef<'c>; +} + +/// Builder for constructing a [`Pool`] with custom attributes. +/// +/// Allows setting database name, host, port, and other identifying information +/// for tracing purposes. +#[derive(Debug)] +pub struct PoolBuilder { + pool: sqlx::Pool, + attributes: Attributes, +} + +// this is required because `pool.connect_options().to_url_lossy()` panics with sqlite +#[cfg(feature = "postgres")] +impl From> for PoolBuilder { + /// Create a new builder from an existing SQLx pool. + fn from(pool: sqlx::Pool) -> Self { + use sqlx::ConnectOptions; + + let url = pool.connect_options().to_url_lossy(); + let attributes = Attributes { + name: None, + host: url.host_str().map(String::from), + port: url.port(), + database: url + .path_segments() + .and_then(|mut segments| segments.next().map(String::from)), + }; + Self { pool, attributes } + } +} + +// this is required because `pool.connect_options().to_url_lossy()` panics with sqlite +#[cfg(feature = "sqlite")] +impl From> for PoolBuilder { + /// Create a new builder from an existing SQLx pool. + fn from(pool: sqlx::Pool) -> Self { + let attributes = Attributes { + name: None, + host: pool + .connect_options() + .get_filename() + .to_str() + .map(String::from), + port: None, + database: None, + }; + Self { pool, attributes } + } +} + +impl PoolBuilder { + /// Set a custom name for the pool (for peer.service attribute). + pub fn with_name(mut self, name: impl Into) -> Self { + self.attributes.name = Some(name.into()); + self + } + + /// Set the database name attribute. + pub fn with_database(mut self, database: impl Into) -> Self { + self.attributes.database = Some(database.into()); + self + } + + /// Set the host attribute. + pub fn with_host(mut self, host: impl Into) -> Self { + self.attributes.host = Some(host.into()); + self + } + + /// Set the port attribute. + pub fn with_port(mut self, port: u16) -> Self { + self.attributes.port = Some(port); + self + } + + /// Build the [`Pool`] with the configured attributes. + pub fn build(self) -> Pool { + Pool { + inner: self.pool, + attributes: Arc::new(self.attributes), + } + } +} + +/// An asynchronous pool of SQLx database connections with tracing instrumentation. +/// +/// Wraps a SQLx [`Pool`] and propagates tracing attributes to all acquired connections. +#[derive(Debug, Deref, DerefMut)] +pub struct Pool { + #[deref] + #[deref_mut] + inner: sqlx::Pool, + attributes: Arc, +} + +// manually impl `Clone` because `DB` may not be `Clone` +impl Clone for Pool { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + attributes: self.attributes.clone(), + } + } +} + +impl From> for Pool +where + DB: Database, + PoolBuilder: From>, +{ + /// Convert a SQLx [`Pool`] into a tracing-instrumented [`Pool`]. + fn from(inner: sqlx::Pool) -> Self { + PoolBuilder::from(inner).build() + } +} + +/// Wrapper for a mutable SQLx connection reference with tracing attributes. +/// +/// Used internally for transaction and pool connection executors. +pub struct Connection<'c, DB: Database> { + inner: &'c mut DB::Connection, + attributes: Arc, +} + +impl<'c, DB: Database> std::fmt::Debug for Connection<'c, DB> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Connection").finish_non_exhaustive() + } +} + +/// A pooled SQLx connection instrumented for tracing. +/// +/// Implements [`sqlx::Executor`] and propagates tracing attributes. +#[derive(Debug)] +pub struct PoolConnection { + inner: sqlx::pool::PoolConnection, + attributes: Arc, +} + +/// An in-progress database transaction or savepoint, instrumented for tracing. +/// +/// Wraps a SQLx [`Transaction`] and propagates tracing attributes. +#[derive(Debug)] +pub struct Transaction<'c, DB: Database> { + inner: sqlx::Transaction<'c, DB>, + attributes: Arc, +} + +/// Acquire connections or transactions from a database in a generic way. +/// +/// Equivalent of [`sqlx::Acquire`] with tracing. +pub trait Acquire<'c> { + type Database: Database; + + fn acquire( + self, + ) -> BoxFuture<'c, Result, sqlx::Error>>; + + fn begin( + self, + ) -> BoxFuture<'c, Result, sqlx::Error>>; +} + +#[derive(Debug)] +pub enum AnyConnection<'c, DB: Database> { + Pool(PoolConnection), + Raw(Connection<'c, DB>), +} diff --git a/packages/sqlx-tracing/src/pool.rs b/packages/sqlx-tracing/src/pool.rs new file mode 100644 index 000000000..c903f28f1 --- /dev/null +++ b/packages/sqlx-tracing/src/pool.rs @@ -0,0 +1,310 @@ +use futures::{StreamExt, TryStreamExt, future::BoxFuture}; +use tracing::Instrument; + +use crate::AnyConnection; + +impl<'c, DB> crate::Acquire<'c> for &'c crate::Pool +where + DB: crate::Database, +{ + type Database = DB; + + fn acquire( + self, + ) -> BoxFuture<'c, Result, sqlx::Error>> { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.acquire", attrs); + let fut = self.inner.acquire(); + let fut = async move { + let conn = fut.await.inspect_err(crate::span::record_error)?; + let conn = crate::PoolConnection { + inner: conn, + attributes: self.attributes.clone(), + }; + let conn = AnyConnection::Pool(conn); + Ok::<_, sqlx::Error>(conn) + }; + Box::pin(fut.instrument(span)) + } + + fn begin( + self, + ) -> BoxFuture< + 'c, + Result, sqlx::Error>, + > { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.begin", attrs); + let fut = self.inner.begin(); + Box::pin( + async move { + let txn = fut.await.inspect_err(crate::span::record_error)?; + let txn = crate::Transaction { + inner: txn, + attributes: self.attributes.clone(), + }; + Ok::<_, sqlx::Error>(txn) + } + .instrument(span), + ) + } +} + +impl crate::Pool { + /// Retrieves a connection and immediately begins a new transaction. + /// + /// The returned [`Transaction`] is instrumented for tracing. + /// + /// [`Transaction`]: crate::Transaction + pub async fn begin( + &self, + ) -> Result, sqlx::Error> { + self.inner.begin().await.map(|inner| crate::Transaction { + inner, + attributes: self.attributes.clone(), + }) + } + + /// Acquires a pooled connection, instrumented for tracing. + pub async fn acquire( + &self, + ) -> Result, sqlx::Error> { + self.inner + .acquire() + .await + .map(|inner| crate::PoolConnection { + attributes: self.attributes.clone(), + inner, + }) + } +} + +impl<'p, DB> sqlx::Executor<'p> for &crate::Pool +where + DB: crate::Database, + for<'c> &'c mut DB::Connection: sqlx::Executor<'c, Database = DB>, +{ + type Database = DB; + + #[doc(hidden)] + fn describe<'e, 'q: 'e>( + self, + sql: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result, sqlx::Error>, + > { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.describe", attrs, sql); + let fut = self.inner.describe(sql); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute", attrs, sql); + let fut = self.inner.execute(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute_many", attrs, sql); + let stream = self.inner.execute_many(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch", attrs, sql); + let stream = self.inner.fetch(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_all<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let fut = self.inner.fetch_all(query); + Box::pin( + async move { + fut.await + .inspect(|res| { + let span = tracing::Span::current(); + span.record("db.response.returned_rows", res.len()); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result< + sqlx::Either< + ::QueryResult, + ::Row, + >, + sqlx::Error, + >, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let stream = self.inner.fetch_many(query); + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_one<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_one", attrs, sql); + let fut = self.inner.fetch_one(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_one) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_optional<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_optional", attrs, sql); + let fut = self.inner.fetch_optional(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_optional) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn prepare<'e, 'q: 'e>( + self, + query: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare", attrs, query); + let fut = self.inner.prepare(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn prepare_with<'e, 'q: 'e>( + self, + sql: &'q str, + parameters: &'e [::TypeInfo], + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare_with", attrs, sql); + let fut = self.inner.prepare_with(sql, parameters); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } +} diff --git a/packages/sqlx-tracing/src/postgres.rs b/packages/sqlx-tracing/src/postgres.rs new file mode 100644 index 000000000..a973ccedd --- /dev/null +++ b/packages/sqlx-tracing/src/postgres.rs @@ -0,0 +1,23 @@ +impl crate::Database for sqlx::Postgres { + const SYSTEM: &'static str = "postgresql"; + + type ConnectionRef<'a> = &'a mut sqlx::PgConnection; + + fn cast_connection<'c>( + conn: &'c mut ::Connection, + ) -> Self::ConnectionRef<'c> { + conn + } + + // fn cast_pool_connection<'c>( + // conn: &'c mut PoolConnection, + // ) -> Self::PoolConnection<'c> { + // &mut conn.inner + // } + + // fn cast_raw_connection<'c>( + // conn: &'c mut ::Connection, + // ) -> Self::RawConnection<'c> { + // conn + // } +} diff --git a/packages/sqlx-tracing/src/span.rs b/packages/sqlx-tracing/src/span.rs new file mode 100644 index 000000000..6d4cf20be --- /dev/null +++ b/packages/sqlx-tracing/src/span.rs @@ -0,0 +1,88 @@ +/// Macro to create a tracing span for a SQLx operation with OpenTelemetry-compatible fields. +/// +/// - `$name`: The operation name (e.g., "sqlx.execute"). +/// - `$statement`: The SQL statement being executed. +/// - `$attributes`: Connection or pool attributes for peer and db context. +/// +/// This macro is used internally by the crate to instrument all major SQLx operations. +#[macro_export] +macro_rules! instrument { + ($name:expr, $attributes:expr $(, $statement:expr)? ) => { + tracing::info_span!( + $name, + // Database name (if available) + "db.name" = $attributes.database, + // Operation type (filled by SQLx or left empty) + "db.operation" = ::tracing::field::Empty, + // The SQL query text + $( "db.query.text" = $statement, )? + // Number of affected rows (to be filled after execution) + "db.response.affected_rows" = ::tracing::field::Empty, + // Number of returned rows (to be filled after execution) + "db.response.returned_rows" = ::tracing::field::Empty, + // Status code of the response (to be filled after execution) + "db.response.status_code" = ::tracing::field::Empty, + // Table name (optional, left empty) + "db.sql.table" = ::tracing::field::Empty, + // Database system (e.g., "postgresql", "sqlite") + "db.system.name" = DB::SYSTEM, + // Error type, message, and stacktrace (to be filled on error) + "error.type" = ::tracing::field::Empty, + "error.message" = ::tracing::field::Empty, + "error.stacktrace" = ::tracing::field::Empty, + // Peer (server) host and port + "net.peer.name" = $attributes.host, + "net.peer.port" = $attributes.port, + // OpenTelemetry semantic fields + "otel.kind" = "client", + "otel.status_code" = ::tracing::field::Empty, + "otel.status_description" = ::tracing::field::Empty, + // Peer service name (if set) + "peer.service" = $attributes.name, + ) + }; +} + +/// Records that a single row was returned in the current tracing span. +/// Used for fetch_one operations. +pub fn record_one(_value: &T) { + let span = tracing::Span::current(); + span.record("db.response.returned_rows", 1); +} + +/// Records whether an optional row was returned in the current tracing span. +/// Used for fetch_optional operations. +pub fn record_optional(value: &Option) { + let span = tracing::Span::current(); + span.record( + "db.response.returned_rows", + if value.is_some() { 1 } else { 0 }, + ); +} + +/// Records error details in the current tracing span for a SQLx error. +/// Sets OpenTelemetry status and error fields for observability backends. +pub fn record_error(err: &sqlx::Error) { + let span = tracing::Span::current(); + // Mark the span as an error for OpenTelemetry + span.record("otel.status_code", "error"); + span.record("otel.status_description", err.to_string()); + // Classify error type as client or server + match err { + sqlx::Error::ColumnIndexOutOfBounds { .. } + | sqlx::Error::ColumnDecode { .. } + | sqlx::Error::ColumnNotFound(_) + | sqlx::Error::Decode { .. } + | sqlx::Error::Encode { .. } + | sqlx::Error::RowNotFound + | sqlx::Error::TypeNotFound { .. } => { + span.record("error.type", "client"); + } + _ => { + span.record("error.type", "server"); + } + } + // Attach error message and stacktrace for debugging + span.record("error.message", err.to_string()); + span.record("error.stacktrace", format!("{err:?}")); +} diff --git a/packages/sqlx-tracing/src/sqlite.rs b/packages/sqlx-tracing/src/sqlite.rs new file mode 100644 index 000000000..2e60f06d9 --- /dev/null +++ b/packages/sqlx-tracing/src/sqlite.rs @@ -0,0 +1,11 @@ +impl crate::Database for sqlx::Sqlite { + const SYSTEM: &'static str = "sqlite"; + + type ConnectionRef<'a> = &'a mut sqlx::SqliteConnection; + + fn cast_connection<'c>( + conn: &'c mut ::Connection, + ) -> Self::ConnectionRef<'c> { + conn + } +} diff --git a/packages/sqlx-tracing/src/transaction.rs b/packages/sqlx-tracing/src/transaction.rs new file mode 100644 index 000000000..3eb7b88cb --- /dev/null +++ b/packages/sqlx-tracing/src/transaction.rs @@ -0,0 +1,334 @@ +use futures::{StreamExt, TryStreamExt, future::BoxFuture}; +use sqlx::{Acquire, Error}; +use tracing::Instrument; + +use crate::AnyConnection; + +impl<'c, DB> crate::Transaction<'c, DB> +where + DB: crate::Database, +{ + /// Returns a tracing-instrumented executor for this transaction. + /// + /// This allows running queries with full span context and attributes. + pub fn executor(&mut self) -> crate::Connection<'_, DB> { + crate::Connection { + inner: &mut *self.inner, + attributes: self.attributes.clone(), + } + } + + /// Commits this transaction or savepoint. + pub async fn commit(self) -> Result<(), Error> { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.commit", attrs); + let fut = self.inner.commit(); + fut.instrument(span).await + } + + /// Aborts this transaction or savepoint. + pub async fn rollback(self) -> Result<(), Error> { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.rollback", attrs); + let fut = self.inner.rollback(); + fut.instrument(span).await + } +} + +impl<'c, 't, DB> crate::Acquire<'t> for &'t mut crate::Transaction<'c, DB> +where + DB: crate::Database, +{ + type Database = DB; + + #[inline] + fn acquire( + self, + ) -> BoxFuture<'t, Result, sqlx::Error>> { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.acquire", attrs); + let fut = self.inner.acquire(); + let fut = async move { + let conn = fut.await.inspect_err(crate::span::record_error)?; + let conn = crate::Connection { + inner: conn, + attributes: attrs.clone(), + }; + let conn = AnyConnection::Raw(conn); + Ok(conn) + }; + Box::pin(fut.instrument(span)) + } + + fn begin( + self, + ) -> BoxFuture< + 't, + Result, sqlx::Error>, + > { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.begin", attrs); + let fut = self.inner.begin(); + let fut = async move { + let txn = fut.await.inspect_err(crate::span::record_error)?; + let txn = crate::Transaction { + inner: txn, + attributes: attrs.clone(), + }; + Ok(txn) + }; + Box::pin(fut.instrument(span)) + } +} + +/// Implements `sqlx::Executor` for a mutable reference to a tracing-instrumented transaction. +/// +/// Each method creates a tracing span for the SQL operation, attaches relevant attributes, +/// and records errors or row counts as appropriate for observability. +impl<'c, 't, DB> sqlx::Executor<'t> for &'t mut crate::Transaction<'c, DB> +where + DB: crate::Database, + for<'a> &'a mut DB::Connection: sqlx::Executor<'a, Database = DB>, +{ + type Database = DB; + + #[doc(hidden)] + fn describe<'e, 'q: 'e>( + self, + sql: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result, sqlx::Error>, + > + where + 't: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.describe", attrs, sql); + Box::pin( + async move { + let fut = (&mut self.inner).describe(sql); + fut.await.inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn execute<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute", attrs, sql); + let fut = (&mut self.inner).execute(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn execute_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::QueryResult, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.execute_many", attrs, sql); + let stream = (&mut self.inner).execute_many(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch", attrs, sql); + let stream = (&mut self.inner).fetch(query); + use futures::StreamExt; + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_all<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let fut = (&mut self.inner).fetch_all(query); + Box::pin( + async move { + fut.await + .inspect(|res| { + let span = tracing::Span::current(); + span.record("db.response.returned_rows", res.len()); + }) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_many<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::stream::BoxStream< + 'e, + Result< + sqlx::Either< + ::QueryResult, + ::Row, + >, + sqlx::Error, + >, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_all", attrs, sql); + let stream = (&mut self.inner).fetch_many(query); + Box::pin( + stream + .inspect(move |_| { + let _enter = span.enter(); + }) + .inspect_err(crate::span::record_error), + ) + } + + fn fetch_one<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result<::Row, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_one", attrs, sql); + let fut = (&mut self.inner).fetch_one(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_one) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn fetch_optional<'e, 'q: 'e, E>( + self, + query: E, + ) -> futures::future::BoxFuture< + 'e, + Result::Row>, sqlx::Error>, + > + where + E: 'q + sqlx::Execute<'q, Self::Database>, + 't: 'e, + { + let sql = query.sql(); + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.fetch_optional", attrs, sql); + let fut = (&mut self.inner).fetch_optional(query); + Box::pin( + async move { + fut.await + .inspect(crate::span::record_optional) + .inspect_err(crate::span::record_error) + } + .instrument(span), + ) + } + + fn prepare<'e, 'q: 'e>( + self, + query: &'q str, + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 't: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare", attrs, query); + let fut = (&mut self.inner).prepare(query); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } + + fn prepare_with<'e, 'q: 'e>( + self, + sql: &'q str, + parameters: &'e [::TypeInfo], + ) -> futures::future::BoxFuture< + 'e, + Result<::Statement<'q>, sqlx::Error>, + > + where + 't: 'e, + { + let attrs = &self.attributes; + let span = crate::instrument!("sqlx.prepare_with", attrs, sql); + let fut = (&mut self.inner).prepare_with(sql, parameters); + Box::pin( + async move { fut.await.inspect_err(crate::span::record_error) } + .instrument(span), + ) + } +} diff --git a/packages/sqlx-tracing/tests/api.rs b/packages/sqlx-tracing/tests/api.rs new file mode 100644 index 000000000..933d217fe --- /dev/null +++ b/packages/sqlx-tracing/tests/api.rs @@ -0,0 +1,87 @@ +//! Test that valid uses of the API compile. +#![expect(dead_code, reason = "only here to check that the code compiles")] + +use sqlx::Postgres; + +async fn a(db: sqlx_tracing::Pool) { + let _conn: sqlx_tracing::PoolConnection = + db.acquire().await.unwrap(); +} + +async fn b<'a, E>(exec: E) +where + E: sqlx_tracing::Acquire<'a, Database = Postgres>, +{ + let mut conn: sqlx_tracing::AnyConnection = + exec.acquire().await.unwrap(); + // sqlx::query("SELECT 1").execute(&mut conn).await.unwrap(); + sqlx::query("SELECT 1").execute(&mut conn).await.unwrap(); +} + +async fn c<'a, E>(exec: E) +where + E: sqlx_tracing::Executor<'a, Database = Postgres>, +{ + sqlx::query("SELECT 1").execute(exec).await.unwrap(); +} + +pub async fn list_many<'a, E>(exec: E) +where + E: sqlx::Executor<'a, Database = Postgres>, +{ + sqlx::query( + " + SELECT + id, enum_id, value, ordering, + metadata, created + FROM loader_field_enum_values + WHERE enum_id = ANY($1) + ORDER BY enum_id, ordering, created DESC + ", + ) + .fetch_all(exec) + .await + .unwrap(); +} + +async fn insert_sqlx(transaction: &mut sqlx::Transaction<'_, Postgres>) { + get_id_sqlx(&mut *transaction).await; +} + +async fn insert<'t, 'c>( + transaction: &'t mut sqlx_tracing::Transaction<'c, Postgres>, +) { + get_id(&mut *transaction).await; + get_id(&mut *transaction).await; + + sqlx::query("SELECT 1") + .execute(&mut *transaction) + .await + .unwrap(); + sqlx::query("SELECT 1") + .execute(&mut *transaction) + .await + .unwrap(); +} + +async fn get_id_sqlx<'a, E>(_executor: E) +where + E: sqlx::Acquire<'a, Database = sqlx::Postgres>, +{ +} + +async fn get_id<'a, E>(_executor: E) +where + E: sqlx_tracing::Acquire<'a, Database = sqlx::Postgres>, +{ +} + +async fn d<'a, E>(exec: E) +where + E: sqlx_tracing::Acquire<'a, Database = Postgres>, +{ + let mut exec = exec.acquire().await.unwrap(); + + sqlx::query("SELECT 1").fetch_one(&mut exec).await.unwrap(); + sqlx::query("SELECT 1").fetch_one(&mut exec).await.unwrap(); +} diff --git a/packages/sqlx-tracing/tests/common.rs b/packages/sqlx-tracing/tests/common.rs new file mode 100644 index 000000000..a7d101f37 --- /dev/null +++ b/packages/sqlx-tracing/tests/common.rs @@ -0,0 +1,47 @@ +use std::time::Duration; + +use opentelemetry::trace::{FutureExt, TraceContextExt, Tracer}; + +pub async fn should_trace<'c, DB, E>( + name: &'static str, + system: &'static str, + observability: &opentelemetry_testing::ObservabilityContainer, + provider: &opentelemetry_testing::OpenTelemetryProvider, + executor: E, +) where + DB: sqlx::Database, + E: sqlx::Executor<'c, Database = DB>, + for<'q> DB::Arguments<'q>: 'q + sqlx::IntoArguments<'q, DB>, + (i32,): Send + Unpin + for<'r> sqlx::FromRow<'r, DB::Row>, +{ + let scope = format!("should_{name}_{system}"); + let tracer = opentelemetry::global::tracer(scope.clone()); + let span = tracer.span_builder(name).start(&tracer); + let ctx = opentelemetry::Context::new().with_span(span); + + let result: Option = sqlx::query_scalar("select 1") + .fetch_optional(executor) + .with_context(ctx) + .await + .unwrap(); + + assert_eq!(result, Some(1)); + + provider.flush(); + + tokio::time::sleep(Duration::from_secs(1)).await; + + let traces = observability.json_traces(); + let scope_span = traces.find_scope_span(&scope).unwrap(); + let entry = scope_span.first_span().unwrap(); + assert_eq!(entry.name, name); + let next = traces + .find_child(&entry.span_id, "sqlx.fetch_optional") + .unwrap(); + assert_eq!(next.string_attribute("db.system.name").unwrap(), system); + assert_eq!(next.string_attribute("db.query.text").unwrap(), "select 1"); + assert_eq!( + next.int_attribute("db.response.returned_rows").unwrap(), + "1" + ); +} diff --git a/packages/sqlx-tracing/tests/postgres.rs b/packages/sqlx-tracing/tests/postgres.rs new file mode 100644 index 000000000..0b2d0c6f9 --- /dev/null +++ b/packages/sqlx-tracing/tests/postgres.rs @@ -0,0 +1,80 @@ +#![cfg(feature = "postgres")] + +use std::time::Duration; + +use sqlx::Postgres; +use testcontainers::{ + GenericImage, ImageExt, + core::{ContainerPort, WaitFor}, + runners::AsyncRunner, +}; + +mod common; + +#[derive(Debug)] +struct PostgresContainer { + container: testcontainers::ContainerAsync, +} + +impl PostgresContainer { + async fn create() -> Self { + let container = GenericImage::new("postgres", "15-alpine") + .with_wait_for(WaitFor::message_on_stderr( + "database system is ready to accept connections", + )) + .with_exposed_port(ContainerPort::Tcp(5432)) + .with_env_var("POSTGRES_USER", "postgres") + .with_env_var("POSTGRES_DB", "postgres") + .with_env_var("POSTGRES_HOST_AUTH_METHOD", "trust") + .with_startup_timeout(Duration::from_secs(60)) + .start() + .await + .expect("starting a postgres database"); + + Self { container } + } + + async fn client(&self) -> sqlx_tracing::Pool { + let port = self.container.get_host_port_ipv4(5432).await.unwrap(); + let url = format!("postgres://postgres@localhost:{port}/postgres"); + sqlx::PgPool::connect(&url) + .await + .map(sqlx_tracing::Pool::from) + .unwrap() + } +} + +#[tokio::test] +async fn execute() { + let observability = opentelemetry_testing::ObservabilityContainer::create().await; + let provider = observability.install().await; + + let container = PostgresContainer::create().await; + let pool = container.client().await; + + common::should_trace("trace_pool", "postgresql", &observability, &provider, &pool).await; + + { + let mut conn = pool.acquire().await.unwrap(); + common::should_trace( + "trace_conn", + "postgresql", + &observability, + &provider, + &mut conn, + ) + .await; + } + + { + let mut tx: sqlx_tracing::Transaction<'_, Postgres> = pool.begin().await.unwrap(); + common::should_trace( + "trace_tx", + "postgresql", + &observability, + &provider, + &mut tx.executor(), + ) + .await; + } +} diff --git a/packages/sqlx-tracing/tests/sqlite.rs b/packages/sqlx-tracing/tests/sqlite.rs new file mode 100644 index 000000000..921be0a69 --- /dev/null +++ b/packages/sqlx-tracing/tests/sqlite.rs @@ -0,0 +1,33 @@ +#![cfg(feature = "sqlite")] + +use sqlx::Sqlite; + +mod common; + +#[tokio::test] +async fn execute() { + let observability = opentelemetry_testing::ObservabilityContainer::create().await; + let provider = observability.install().await; + + let pool = sqlx::SqlitePool::connect(":memory:").await.unwrap(); + let pool = sqlx_tracing::Pool::from(pool); + + common::should_trace("trace_pool", "sqlite", &observability, &provider, &pool).await; + + { + let mut conn = pool.acquire().await.unwrap(); + common::should_trace("trace_conn", "sqlite", &observability, &provider, &mut conn).await; + } + + { + let mut tx: sqlx_tracing::Transaction<'_, Sqlite> = pool.begin().await.unwrap(); + common::should_trace( + "trace_tx", + "sqlite", + &observability, + &provider, + &mut tx.executor(), + ) + .await; + } +}