diff --git a/Cargo.lock b/Cargo.lock index f2f30351fd..895fd55ab3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,6 +343,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-compression" version = "0.4.5" @@ -359,6 +370,35 @@ dependencies = [ "zstd-safe 7.0.0", ] +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand 1.9.0", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + [[package]] name = "async-graphql" version = "6.0.11" @@ -446,6 +486,35 @@ dependencies = [ "warp", ] +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener", +] + [[package]] name = "async-recursion" version = "1.0.5" @@ -457,6 +526,32 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -479,6 +574,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + [[package]] name = "async-trait" version = "0.1.74" @@ -503,13 +604,29 @@ dependencies = [ [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits 0.2.17", ] +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand", +] + [[package]] name = "auto_impl" version = "1.1.0" @@ -695,6 +812,9 @@ name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -758,6 +878,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand 1.9.0", + "futures-lite", + "log", +] + [[package]] name = "brotli" version = "3.4.0" @@ -1673,6 +1808,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "concurrent-queue" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console" version = "0.15.7" @@ -2078,6 +2222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -2561,6 +2706,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "eth-keystore" version = "0.5.0" @@ -2913,6 +3069,15 @@ dependencies = [ "serde", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -2977,13 +3142,12 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.14" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ "futures-core", "futures-sink", - "pin-project", "spin 0.9.8", ] @@ -3018,7 +3182,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix", + "rustix 0.38.26", "windows-sys 0.48.0", ] @@ -3081,13 +3245,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot 0.12.1", ] [[package]] @@ -3096,6 +3260,21 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-locks" version = "0.7.1" @@ -3727,7 +3906,7 @@ dependencies = [ "gix-command", "gix-config-value", "parking_lot 0.12.1", - "rustix", + "rustix 0.38.26", "thiserror", ] @@ -3910,7 +4089,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" dependencies = [ - "fastrand", + "fastrand 2.0.1", ] [[package]] @@ -4186,6 +4365,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -4580,6 +4768,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipfs-api-backend-hyper" version = "0.6.0" @@ -4644,7 +4843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix", + "rustix 0.38.26", "windows-sys 0.48.0", ] @@ -4923,6 +5122,15 @@ dependencies = [ "libc", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lalrpop" version = "0.20.0" @@ -4999,15 +5207,21 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.24.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "cc", "pkg-config", "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -5029,6 +5243,9 @@ name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "lru" @@ -5355,6 +5572,23 @@ dependencies = [ "serde", ] +[[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 0.2.17", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-complex" version = "0.2.4" @@ -5375,6 +5609,17 @@ dependencies = [ "num-traits 0.2.17", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.17", +] + [[package]] name = "num-modular" version = "0.5.1" @@ -5582,6 +5827,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.11.2" @@ -5708,6 +5959,15 @@ dependencies = [ "base64 0.13.1", ] +[[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.1" @@ -5868,6 +6128,17 @@ 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" @@ -5884,6 +6155,22 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "portable-atomic" version = "1.5.1" @@ -6386,7 +6673,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.3", + "webpki-roots", "winreg", ] @@ -6460,6 +6747,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits 0.2.17", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -6487,6 +6794,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.26" @@ -6496,7 +6817,7 @@ dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.12", "windows-sys 0.52.0", ] @@ -7362,23 +7683,27 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.7.7", + "ahash 0.8.6", + "async-io", + "async-std", "atoi", - "bitflags 1.3.2", "byteorder", "bytes", "chrono", @@ -7387,44 +7712,53 @@ dependencies = [ "dotenvy", "either", "event-listener", - "flume", "futures-channel", "futures-core", - "futures-executor", "futures-intrusive", + "futures-io", "futures-util", "hashlink", "hex", - "indexmap 1.9.3", - "itoa", - "libc", - "libsqlite3-sys", + "indexmap 2.1.0", "log", "memchr", "once_cell", "paste", "percent-encoding", - "rustls 0.20.9", - "rustls-pemfile", "serde", + "serde_json", "sha2", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", + "tokio", "tokio-stream", + "tracing", "url", "uuid 1.6.1", - "webpki-roots 0.22.6", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" dependencies = [ + "async-std", + "atomic-write-file", "dotenvy", "either", "heck 0.4.1", @@ -7436,20 +7770,124 @@ dependencies = [ "serde_json", "sha2", "sqlx-core", - "sqlx-rt", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", "syn 1.0.109", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +dependencies = [ + "atoi", + "base64 0.21.5", + "bitflags 2.4.1", + "byteorder", + "bytes", + "chrono", + "crc", + "digest 0.10.7", + "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", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid 1.6.1", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" dependencies = [ + "atoi", + "base64 0.21.5", + "bitflags 2.4.1", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-rustls 0.23.4", + "rand", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid 1.6.1", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "regex", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", + "uuid 1.6.1", ] [[package]] @@ -7850,9 +8288,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.0.1", "redox_syscall 0.4.1", - "rustix", + "rustix 0.38.26", "windows-sys 0.48.0", ] @@ -8082,7 +8520,7 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots 0.25.3", + "webpki-roots", ] [[package]] @@ -8870,6 +9308,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -8907,6 +9351,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" + [[package]] name = "vcpkg" version = "0.2.15" @@ -8928,6 +9378,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" version = "2.4.0" @@ -9083,15 +9539,6 @@ dependencies = [ "untrusted 0.9.0", ] -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.25.3" @@ -9107,9 +9554,15 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.26", ] +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index f1254fa576..ea2b044bb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,7 +87,7 @@ serde = { version = "1.0.156", features = [ "derive" ] } serde_json = "1.0" serde_with = "2.3.1" smol_str = { version = "0.2.0", features = [ "serde" ] } -sqlx = { version = "0.6.2", features = [ "chrono", "macros", "offline", "runtime-actix-rustls", "sqlite", "uuid" ] } +sqlx = { version = "0.7.2", features = [ "chrono", "macros", "runtime-async-std", "runtime-tokio", "sqlite", "uuid", "regexp" ] } starknet = "0.7.0" starknet-crypto = "0.6.1" starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "ecc9b6946ef13003da202838e4124a9ad2efabb0" } diff --git a/crates/torii/client/src/client/mod.rs b/crates/torii/client/src/client/mod.rs index 7bed643a32..9520ef7782 100644 --- a/crates/torii/client/src/client/mod.rs +++ b/crates/torii/client/src/client/mod.rs @@ -99,12 +99,12 @@ impl Client { self.subscribed_entities.entities_keys.read() } - /// Retrieves entities matching specified keys and/or model name in query parameter. + /// Retrieves entities matching query parameter. /// - /// The query can include keys and a model name, both optional. Without parameters, it fetches - /// all entities, which is less efficient as it requires additional queries for each - /// entity's model data. Specifying a model name optimizes the process by limiting the - /// retrieval to entities with that model, requiring just one query. + /// The query param includes an optional clause for filtering. Without clause, it fetches ALL + /// entities, this is less efficient as it requires an additional query for each entity's + /// model data. Specifying a clause can optimize the query by limiting the retrieval to specific + /// type of entites matching keys and/or models. pub async fn entities(&self, query: Query) -> Result, Error> { let mut grpc_client = self.inner.write().await; let RetrieveEntitiesResponse { entities } = grpc_client.retrieve_entities(query).await?; diff --git a/crates/torii/core/src/cache.rs b/crates/torii/core/src/cache.rs index dc8d39bc63..0a3ae7c1ec 100644 --- a/crates/torii/core/src/cache.rs +++ b/crates/torii/core/src/cache.rs @@ -11,18 +11,27 @@ type ModelName = String; pub struct ModelCache { pool: SqlitePool, - schemas: RwLock>, + cache: RwLock>, } impl ModelCache { pub fn new(pool: SqlitePool) -> Self { - Self { pool, schemas: RwLock::new(HashMap::new()) } + Self { pool, cache: RwLock::new(HashMap::new()) } + } + + pub async fn schemas(&self, models: Vec<&str>) -> Result, Error> { + let mut schemas = Vec::with_capacity(models.len()); + for model in models { + schemas.push(self.schema(model).await?); + } + + Ok(schemas) } pub async fn schema(&self, model: &str) -> Result { { - let schemas = self.schemas.read().await; - if let Some(schema) = schemas.get(model) { + let cache = self.cache.read().await; + if let Some(schema) = cache.get(model) { return Ok(schema.clone()); } } @@ -44,13 +53,13 @@ impl ModelCache { } let ty = parse_sql_model_members(model, &model_members); - let mut schemas = self.schemas.write().await; - schemas.insert(model.into(), ty.clone()); + let mut cache = self.cache.write().await; + cache.insert(model.into(), ty.clone()); Ok(ty) } pub async fn clear(&self) { - self.schemas.write().await.clear(); + self.cache.write().await.clear(); } } diff --git a/crates/torii/core/src/error.rs b/crates/torii/core/src/error.rs index 0d73633076..43f8b628be 100644 --- a/crates/torii/core/src/error.rs +++ b/crates/torii/core/src/error.rs @@ -35,6 +35,8 @@ pub enum ParseError { pub enum QueryError { #[error("unsupported query")] UnsupportedQuery, + #[error("missing param: {0}")] + MissingParam(String), #[error("model not found: {0}")] ModelNotFound(String), #[error("exceeds sqlite `JOIN` limit (64)")] diff --git a/crates/torii/core/src/model.rs b/crates/torii/core/src/model.rs index 883470e1b1..cf0bd22154 100644 --- a/crates/torii/core/src/model.rs +++ b/crates/torii/core/src/model.rs @@ -201,11 +201,11 @@ pub fn build_sql_query(model_schemas: &Vec) -> Result { let selections_clause = global_selections.join(", "); let join_clause = global_tables .into_iter() - .map(|table| format!(" LEFT JOIN {table} ON entities.id = {table}.entity_id")) + .map(|table| format!(" JOIN {table} ON entities.id = {table}.entity_id")) .collect::>() .join(" "); - Ok(format!("SELECT entities.keys, {selections_clause} FROM entities{join_clause}")) + Ok(format!("SELECT entities.id, entities.keys, {selections_clause} FROM entities{join_clause}")) } /// Populate the values of a Ty (schema) from SQLite row. @@ -504,14 +504,9 @@ mod tests { }); let query = build_sql_query(&vec![ty]).unwrap(); - println!("{query}"); assert_eq!( query, - "SELECT entities.keys, Position.external_name AS \"Position.name\", \ - Position.external_age AS \"Position.age\", Position$Vec2.external_x AS \ - \"Position$Vec2.x\", Position$Vec2.external_y AS \"Position$Vec2.y\" FROM entities \ - LEFT JOIN Position ON entities.id = Position.entity_id LEFT JOIN Position$Vec2 ON \ - entities.id = Position$Vec2.entity_id" + r#"SELECT entities.id, entities.keys, Position.external_name AS "Position.name", Position.external_age AS "Position.age", Position$Vec2.external_x AS "Position$Vec2.x", Position$Vec2.external_y AS "Position$Vec2.y" FROM entities JOIN Position ON entities.id = Position.entity_id JOIN Position$Vec2 ON entities.id = Position$Vec2.entity_id"# ); } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index b56ae45e84..3d99a1c6b3 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -53,7 +53,7 @@ impl Sql { let indexer_query = sqlx::query_as::<_, (i64,)>("SELECT head FROM indexers WHERE id = ?") .bind(format!("{:#x}", self.world_address)); - let indexer: (i64,) = indexer_query.fetch_one(&mut conn).await?; + let indexer: (i64,) = indexer_query.fetch_one(&mut *conn).await?; Ok(indexer.0.try_into().expect("doesn't fit in u64")) } @@ -68,7 +68,7 @@ impl Sql { let mut conn: PoolConnection = self.pool.acquire().await?; let meta: World = sqlx::query_as("SELECT * FROM worlds WHERE id = ?") .bind(format!("{:#x}", self.world_address)) - .fetch_one(&mut conn) + .fetch_one(&mut *conn) .await?; Ok(meta) @@ -223,14 +223,14 @@ impl Sql { .bind(format!("{:#x}", key)); let mut conn: PoolConnection = self.pool.acquire().await?; - let row: (i32, String, String) = query.fetch_one(&mut conn).await?; + let row: (i32, String, String) = query.fetch_one(&mut *conn).await?; Ok(serde_json::from_str(&row.2).unwrap()) } pub async fn entities(&self, model: String) -> Result>> { let query = sqlx::query_as::<_, (i32, String, String)>("SELECT * FROM ?").bind(model); let mut conn: PoolConnection = self.pool.acquire().await?; - let mut rows = query.fetch_all(&mut conn).await?; + let mut rows = query.fetch_all(&mut *conn).await?; Ok(rows.drain(..).map(|row| serde_json::from_str(&row.2).unwrap()).collect()) } diff --git a/crates/torii/graphql/src/object/entity.rs b/crates/torii/graphql/src/object/entity.rs index aa19481648..fc0e90077c 100644 --- a/crates/torii/graphql/src/object/entity.rs +++ b/crates/torii/graphql/src/object/entity.rs @@ -139,7 +139,7 @@ fn model_union_field() -> Field { let model_ids: Vec<(String,)> = sqlx::query_as("SELECT model_id from entity_model WHERE entity_id = ?") .bind(&entity_id) - .fetch_all(&mut conn) + .fetch_all(&mut *conn) .await?; let mut results: Vec> = Vec::new(); diff --git a/crates/torii/graphql/src/query/data.rs b/crates/torii/graphql/src/query/data.rs index de04e12e49..80e0c80dc0 100644 --- a/crates/torii/graphql/src/query/data.rs +++ b/crates/torii/graphql/src/query/data.rs @@ -1,7 +1,6 @@ use async_graphql::connection::PageInfo; -use sqlx::pool::PoolConnection; use sqlx::sqlite::SqliteRow; -use sqlx::{Result, Row, Sqlite}; +use sqlx::{Result, Row, SqliteConnection}; use super::filter::{Filter, FilterValue}; use super::order::{CursorDirection, Direction, Order}; @@ -9,7 +8,7 @@ use crate::constants::DEFAULT_LIMIT; use crate::object::connection::{cursor, ConnectionArguments}; pub async fn count_rows( - conn: &mut PoolConnection, + conn: &mut SqliteConnection, table_name: &str, keys: &Option>, filters: &Option>, @@ -26,7 +25,7 @@ pub async fn count_rows( } pub async fn fetch_single_row( - conn: &mut PoolConnection, + conn: &mut SqliteConnection, table_name: &str, id_column: &str, id: &str, @@ -37,7 +36,7 @@ pub async fn fetch_single_row( #[allow(clippy::too_many_arguments)] pub async fn fetch_multiple_rows( - conn: &mut PoolConnection, + conn: &mut SqliteConnection, table_name: &str, id_column: &str, keys: &Option>, diff --git a/crates/torii/graphql/src/query/mod.rs b/crates/torii/graphql/src/query/mod.rs index 140dcc8caa..c7ff3afd09 100644 --- a/crates/torii/graphql/src/query/mod.rs +++ b/crates/torii/graphql/src/query/mod.rs @@ -4,9 +4,8 @@ use async_graphql::dynamic::TypeRef; use async_graphql::{Name, Value}; use convert_case::{Case, Casing}; use dojo_types::primitive::{Primitive, SqlType}; -use sqlx::pool::PoolConnection; use sqlx::sqlite::SqliteRow; -use sqlx::{Row, Sqlite}; +use sqlx::{Row, SqliteConnection}; use torii_core::sql::FELT_DELIMITER; use crate::constants::{BOOLEAN_TRUE, ENTITY_ID_COLUMN, INTERNAL_ENTITY_ID_KEY}; @@ -18,7 +17,7 @@ pub mod filter; pub mod order; pub async fn type_mapping_query( - conn: &mut PoolConnection, + conn: &mut SqliteConnection, model_id: &str, ) -> sqlx::Result { let model_members = fetch_model_members(conn, model_id).await?; @@ -29,7 +28,7 @@ pub async fn type_mapping_query( } async fn fetch_model_members( - conn: &mut PoolConnection, + conn: &mut SqliteConnection, model_id: &str, ) -> sqlx::Result> { sqlx::query_as( diff --git a/crates/torii/graphql/src/schema.rs b/crates/torii/graphql/src/schema.rs index 8f28ad089a..32db9f090a 100644 --- a/crates/torii/graphql/src/schema.rs +++ b/crates/torii/graphql/src/schema.rs @@ -104,7 +104,7 @@ pub async fn build_schema(pool: &SqlitePool) -> Result { async fn build_objects(pool: &SqlitePool) -> Result<(Vec>, Union)> { let mut conn = pool.acquire().await?; - let models: Vec = sqlx::query_as("SELECT * FROM models").fetch_all(&mut conn).await?; + let models: Vec = sqlx::query_as("SELECT * FROM models").fetch_all(&mut *conn).await?; // predefined objects let mut objects: Vec> = vec![ diff --git a/crates/torii/grpc/src/server/mod.rs b/crates/torii/grpc/src/server/mod.rs index dccb730239..de83ad13cb 100644 --- a/crates/torii/grpc/src/server/mod.rs +++ b/crates/torii/grpc/src/server/mod.rs @@ -108,6 +108,43 @@ impl DojoWorld { }) } + async fn entities_all( + &self, + limit: u32, + offset: u32, + ) -> Result, Error> { + let query = r#" + SELECT entities.id, group_concat(entity_model.model_id) as model_names + FROM entities + JOIN entity_model ON entities.id = entity_model.entity_id + GROUP BY entities.id + ORDER BY entities.event_id DESC + LIMIT ? OFFSET ? + "#; + let db_entities: Vec<(String, String)> = + sqlx::query_as(query).bind(limit).bind(offset).fetch_all(&self.pool).await?; + + let mut entities = Vec::with_capacity(db_entities.len()); + for (entity_id, models_str) in db_entities { + let model_names: Vec<&str> = models_str.split(',').collect(); + let schemas = self.model_cache.schemas(model_names).await?; + + let entity_query = format!("{} WHERE entities.id = ?", build_sql_query(&schemas)?); + let row = sqlx::query(&entity_query).bind(&entity_id).fetch_one(&self.pool).await?; + + let mut models = Vec::with_capacity(schemas.len()); + for schema in schemas { + let struct_ty = schema.as_struct().expect("schema should be struct"); + models.push(Self::map_row_to_struct(&schema.name(), struct_ty, &row)?.into()); + } + + let key = FieldElement::from_str(&entity_id).map_err(ParseError::FromStr)?; + entities.push(proto::types::Entity { key: key.to_bytes_be().to_vec(), models }) + } + + Ok(entities) + } + async fn entities_by_keys( &self, keys_clause: proto::types::KeysClause, @@ -128,45 +165,36 @@ impl DojoWorld { .collect::, Error>>()?; let keys_pattern = keys.join("/") + "/%"; - let query = r#" - SELECT entities.id, group_concat(entity_model.model_id) as model_names + let models_query = format!( + r#" + SELECT group_concat(entity_model.model_id) as model_names FROM entities JOIN entity_model ON entities.id = entity_model.entity_id WHERE entities.keys LIKE ? GROUP BY entities.id - ORDER BY entities.event_id DESC - LIMIT ? OFFSET ? - "#; - let db_entities: Vec<(String, String)> = sqlx::query_as(query) + HAVING model_names REGEXP '(^|,){}(,|$)' + LIMIT 1 + "#, + keys_clause.model + ); + let (models_str,): (String,) = + sqlx::query_as(&models_query).bind(&keys_pattern).fetch_one(&self.pool).await?; + + let model_names = models_str.split(',').collect::>(); + let schemas = self.model_cache.schemas(model_names).await?; + + let entities_query = format!( + "{} WHERE entities.keys LIKE ? ORDER BY entities.event_id DESC LIMIT ? OFFSET ?", + build_sql_query(&schemas)? + ); + let db_entities = sqlx::query(&entities_query) .bind(&keys_pattern) .bind(limit) .bind(offset) .fetch_all(&self.pool) .await?; - let mut entities = Vec::new(); - for (entity_id, models_str) in db_entities { - let model_names: Vec<&str> = models_str.split(',').collect(); - let mut schemas = Vec::new(); - for model in &model_names { - schemas.push(self.model_cache.schema(model).await?); - } - - let entity_query = - format!("{} WHERE {}.entity_id = ?", build_sql_query(&schemas)?, schemas[0].name()); - let row = sqlx::query(&entity_query).bind(&entity_id).fetch_one(&self.pool).await?; - - let mut models = Vec::new(); - for schema in schemas { - let struct_ty = schema.as_struct().expect("schema should be struct"); - models.push(Self::map_row_to_proto(&schema.name(), struct_ty, &row)?.into()); - } - - let key = FieldElement::from_str(&entity_id).map_err(ParseError::FromStr)?; - entities.push(proto::types::Entity { key: key.to_bytes_be().to_vec(), models }) - } - - Ok(entities) + db_entities.iter().map(|row| Self::map_row_to_entity(row, &schemas)).collect() } async fn entities_by_attribute( @@ -245,30 +273,54 @@ impl DojoWorld { &self, query: proto::types::Query, ) -> Result { - let clause_type = query - .clause - .ok_or(QueryError::UnsupportedQuery)? - .clause_type - .ok_or(QueryError::UnsupportedQuery)?; - - let entities = match clause_type { - ClauseType::Keys(keys) => { - self.entities_by_keys(keys, query.limit, query.offset).await? - } - ClauseType::Member(attribute) => { - self.entities_by_attribute(attribute, query.limit, query.offset).await? - } - ClauseType::Composite(composite) => { - self.entities_by_composite(composite, query.limit, query.offset).await? + let entities = match query.clause { + None => self.entities_all(query.limit, query.offset).await?, + Some(clause) => { + let clause_type = + clause.clause_type.ok_or(QueryError::MissingParam("clause_type".into()))?; + + match clause_type { + ClauseType::Keys(keys) => { + if keys.keys.is_empty() { + return Err(QueryError::MissingParam("keys".into()).into()); + } + + if keys.model.is_empty() { + return Err(QueryError::MissingParam("model".into()).into()); + } + + self.entities_by_keys(keys, query.limit, query.offset).await? + } + ClauseType::Member(attribute) => { + self.entities_by_attribute(attribute, query.limit, query.offset).await? + } + ClauseType::Composite(composite) => { + self.entities_by_composite(composite, query.limit, query.offset).await? + } + } } }; Ok(RetrieveEntitiesResponse { entities }) } + fn map_row_to_entity(row: &SqliteRow, schemas: &[Ty]) -> Result { + let key = + FieldElement::from_str(&row.get::("id")).map_err(ParseError::FromStr)?; + let models = schemas + .iter() + .map(|schema| { + let struct_ty = schema.as_struct().expect("schema should be struct"); + Self::map_row_to_struct(&schema.name(), struct_ty, row).map(Into::into) + }) + .collect::, Error>>()?; + + Ok(proto::types::Entity { key: key.to_bytes_be().to_vec(), models }) + } + /// Helper function to map Sqlite row to proto::types::Struct // TODO: refactor this to use `map_row_to_ty` from core and implement Ty to protobuf conversion - fn map_row_to_proto( + fn map_row_to_struct( path: &str, struct_ty: &Struct, row: &SqliteRow, @@ -337,7 +389,7 @@ impl DojoWorld { } Ty::Struct(struct_ty) => { let path = [path, &struct_ty.name].join("$"); - Some(proto::types::ty::TyType::Struct(Self::map_row_to_proto( + Some(proto::types::ty::TyType::Struct(Self::map_row_to_struct( &path, struct_ty, row, )?)) } diff --git a/crates/torii/grpc/src/types.rs b/crates/torii/grpc/src/types.rs index 632d2d763c..ddb6820cc2 100644 --- a/crates/torii/grpc/src/types.rs +++ b/crates/torii/grpc/src/types.rs @@ -26,7 +26,7 @@ pub struct Model { #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct Query { - pub clause: Clause, + pub clause: Option, pub limit: u32, pub offset: u32, } @@ -127,7 +127,7 @@ impl TryFrom for dojo_types::WorldMetadata { impl From for proto::types::Query { fn from(value: Query) -> Self { - Self { clause: Some(value.clause.into()), limit: value.limit, offset: value.offset } + Self { clause: value.clause.map(|c| c.into()), limit: value.limit, offset: value.offset } } } diff --git a/crates/torii/server/src/cli.rs b/crates/torii/server/src/cli.rs index a86e95fda9..23eadaaad7 100644 --- a/crates/torii/server/src/cli.rs +++ b/crates/torii/server/src/cli.rs @@ -84,7 +84,8 @@ async fn main() -> anyhow::Result<()> { .expect("Error setting Ctrl-C handler"); let database_url = format!("sqlite:{}", &args.database); - let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true); + let options = + SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true).with_regexp(); let pool = SqlitePoolOptions::new() .min_connections(1) .max_connections(5)