From 71ae6cb64a1b0c0997bb72d750cbc7396a808e34 Mon Sep 17 00:00:00 2001 From: wangyufan Date: Tue, 19 Mar 2024 12:36:23 +0800 Subject: [PATCH] feat(services/surrealdb): support surrealdb service (#4375) --- core/Cargo.lock | 1107 +++++++++++++++++++++++- core/Cargo.toml | 4 +- core/src/services/mod.rs | 7 + core/src/services/surrealdb/backend.rs | 393 +++++++++ core/src/services/surrealdb/docs.md | 55 ++ core/src/services/surrealdb/mod.rs | 20 + core/src/types/scheme.rs | 6 + 7 files changed, 1588 insertions(+), 4 deletions(-) create mode 100644 core/src/services/surrealdb/backend.rs create mode 100644 core/src/services/surrealdb/docs.md create mode 100644 core/src/services/surrealdb/mod.rs diff --git a/core/Cargo.lock b/core/Cargo.lock index dc0c364c59f4..60f55fda267f 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93b8a41dbe230ad5087cc721f8d41611de654542180586b315d9f4cf6b72bef" +dependencies = [ + "psl-types", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -136,12 +145,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "any_ascii" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea50b14b7a4b9343f8c627a7a53c52076482bd4bdad0a24fd3ec533ed616cc2c" + [[package]] name = "anyhow" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arbitrary" version = "1.3.2" @@ -157,12 +181,33 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + [[package]] name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + [[package]] name = "assert-json-diff" version = "2.0.2" @@ -413,6 +458,32 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.0", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -929,6 +1000,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64-simd" version = "0.8.0" @@ -970,6 +1047,19 @@ dependencies = [ "tokio-postgres", ] +[[package]] +name = "bcrypt" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" +dependencies = [ + "base64 0.22.0", + "blowfish", + "getrandom 0.2.12", + "subtle", + "zeroize", +] + [[package]] name = "bigdecimal" version = "0.3.1" @@ -1033,6 +1123,21 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -1057,6 +1162,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -1091,6 +1205,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "borsh" version = "1.3.1" @@ -1170,6 +1294,12 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +[[package]] +name = "bytemuck" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" + [[package]] name = "byteorder" version = "1.5.0" @@ -1292,6 +1422,63 @@ dependencies = [ "libc", ] +[[package]] +name = "cedar-policy" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d91e3b10a0f7f2911774d5e49713c4d25753466f9e11d1cd2ec627f8a2dc857" +dependencies = [ + "cedar-policy-core", + "cedar-policy-validator", + "itertools 0.10.5", + "lalrpop-util", + "ref-cast", + "serde", + "serde_json", + "smol_str", + "thiserror", +] + +[[package]] +name = "cedar-policy-core" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd2315591c6b7e18f8038f0a0529f254235fd902b6c217aabc04f2459b0d9995" +dependencies = [ + "either", + "ipnet", + "itertools 0.10.5", + "lalrpop", + "lalrpop-util", + "lazy_static", + "miette", + "regex", + "rustc_lexer", + "serde", + "serde_json", + "serde_with 3.7.0", + "smol_str", + "stacker", + "thiserror", +] + +[[package]] +name = "cedar-policy-validator" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e756e1b2a5da742ed97e65199ad6d0893e9aa4bd6b34be1de9e70bd1e6adc7df" +dependencies = [ + "cedar-policy-core", + "itertools 0.10.5", + "serde", + "serde_json", + "serde_with 3.7.0", + "smol_str", + "stacker", + "thiserror", + "unicode-security", +] + [[package]] name = "cexpr" version = "0.6.0" @@ -1323,6 +1510,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets 0.52.0", ] @@ -1620,6 +1808,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + [[package]] name = "crossbeam" version = "0.8.4" @@ -1895,6 +2089,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1985,6 +2180,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deunicode" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94" + [[package]] name = "diff" version = "0.1.13" @@ -2003,6 +2204,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dlv-list" version = "0.5.2" @@ -2012,6 +2234,21 @@ dependencies = [ "const-random", ] +[[package]] +name = "dmp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfaa1135a34d26e5cc5b4927a8935af887d4f30a5653a797c33b9a4222beb6d9" +dependencies = [ + "urlencoding", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dotenvy" version = "0.15.7" @@ -2030,6 +2267,16 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" +[[package]] +name = "earcutr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01" +dependencies = [ + "itertools 0.11.0", + "num-traits", +] + [[package]] name = "ecdsa" version = "0.14.8" @@ -2097,6 +2344,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + [[package]] name = "encoding_rs" version = "0.8.33" @@ -2106,6 +2362,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "enum-as-inner" version = "0.4.0" @@ -2271,6 +2533,24 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2414,6 +2694,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fst" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" + [[package]] name = "funty" version = "2.0.0" @@ -2445,6 +2731,19 @@ dependencies = [ "futures-sink", ] +[[package]] +name = "futures-concurrency" +version = "7.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b590a729e1cbaf9ae3ec294143ea034d93cbb1de01c884d04bcd0af8b613d02" +dependencies = [ + "bitvec", + "futures-core", + "pin-project", + "slab", + "smallvec", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -2543,6 +2842,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + [[package]] name = "fxhash" version = "0.2.1" @@ -2603,6 +2911,63 @@ dependencies = [ "version_check", ] +[[package]] +name = "geo" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1645cf1d7fea7dac1a66f7357f3df2677ada708b8d9db8e9b043878930095a96" +dependencies = [ + "earcutr", + "float_next_after", + "geo-types", + "geographiclib-rs", + "log", + "num-traits", + "robust", + "rstar", + "serde", +] + +[[package]] +name = "geo" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4841b40fdbccd4b7042bd6195e4de91da54af34c50632e371bcbfcdfb558b873" +dependencies = [ + "earcutr", + "float_next_after", + "geo-types", + "geographiclib-rs", + "log", + "num-traits", + "robust", + "rstar", + "serde", + "spade", +] + +[[package]] +name = "geo-types" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff16065e5720f376fbced200a5ae0f47ace85fd70b7e54269790281353b6d61" +dependencies = [ + "approx", + "arbitrary", + "num-traits", + "rstar", + "serde", +] + +[[package]] +name = "geographiclib-rs" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e5ed84f8089c70234b0a8e0aedb6dc733671612ddc0d37c6066052f9781960" +dependencies = [ + "libm", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2709,6 +3074,15 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -2795,6 +3169,19 @@ dependencies = [ "log", ] +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version 0.4.0", + "spin 0.9.8", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -2920,6 +3307,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.28" @@ -3030,6 +3423,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -3040,6 +3434,7 @@ checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", "hashbrown 0.14.3", + "serde", ] [[package]] @@ -3189,6 +3584,37 @@ dependencies = [ "log", ] +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax 0.8.2", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata 0.4.5", +] + [[package]] name = "lazy-regex" version = "3.1.0" @@ -3300,6 +3726,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "lexicmp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7378d131ddf24063b32cbd7e91668d183140c4b3906270635a4d633d1068ea5d" +dependencies = [ + "any_ascii", +] + [[package]] name = "libc" version = "0.2.153" @@ -3333,6 +3768,17 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" @@ -3609,6 +4055,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "mini-moka" version = "0.10.3" @@ -3743,7 +4199,7 @@ dependencies = [ "rustls-pemfile", "serde", "serde_bytes", - "serde_with", + "serde_with 1.14.0", "sha-1", "sha2", "socket2 0.4.10", @@ -3865,6 +4321,24 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "034a0ad7deebf0c2abcf2435950a6666c3c15ea9d8fad0c0f48efa8a7f843fed" +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.12", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -3883,6 +4357,21 @@ dependencies = [ "tempfile", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + [[package]] name = "no-std-compat" version = "0.4.1" @@ -4010,6 +4499,27 @@ dependencies = [ "memchr", ] +[[package]] +name = "object_store" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2524735495ea1268be33d200e1ee97455096a0846295a21548cd2f3541de7050" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "futures", + "humantime", + "itertools 0.11.0", + "parking_lot 0.12.1", + "percent-encoding", + "snafu", + "tokio", + "tracing", + "url", + "walkdir", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -4090,6 +4600,7 @@ dependencies = [ "size", "sled", "suppaftp", + "surrealdb", "tikv-client", "tokio", "tokio-postgres", @@ -4388,6 +4899,23 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "path-clean" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" + [[package]] name = "pbkdf2" version = "0.11.0" @@ -4405,6 +4933,8 @@ checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest", "hmac", + "password-hash", + "sha2", ] [[package]] @@ -4474,13 +5004,32 @@ dependencies = [ "indexmap 2.2.2", ] +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.0", +] + [[package]] name = "phf" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_shared", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", ] [[package]] @@ -4492,6 +5041,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.4" @@ -4703,6 +5258,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -4936,6 +5497,21 @@ version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -5014,6 +5590,18 @@ dependencies = [ "serde", ] +[[package]] +name = "quick_cache" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c20af3800cee5134b79a3bd4a3d4b583c16ccfa5f53338f46400851a5b3819" +dependencies = [ + "ahash 0.8.7", + "equivalent", + "hashbrown 0.14.3", + "parking_lot 0.12.1", +] + [[package]] name = "quote" version = "1.0.35" @@ -5040,6 +5628,17 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", + "serde", +] + [[package]] name = "rand" version = "0.7.3" @@ -5217,6 +5816,37 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "reflink-copy" version = "0.1.14" @@ -5338,6 +5968,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "once_cell", "percent-encoding", "pin-project-lite", @@ -5377,6 +6008,37 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" +[[package]] +name = "revision" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87eb86913082f8976b06d07a59f17df9120e6f38b882cf3fc5a45b4499e224b6" +dependencies = [ + "bincode", + "chrono", + "geo 0.26.0", + "regex", + "revision-derive", + "roaring", + "rust_decimal", + "serde", + "thiserror", + "uuid", +] + +[[package]] +name = "revision-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf996fc5f61f1dbec35799b5c00c6dda12e8862e8cb782ed24e10d0292e60ed3" +dependencies = [ + "darling 0.20.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "rfc6979" version = "0.3.1" @@ -5446,6 +6108,23 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "roaring" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1c77081a55300e016cb86f2864415b7518741879db925b8d488a0ee0d2da6bf" +dependencies = [ + "bytemuck", + "byteorder", + "serde", +] + +[[package]] +name = "robust" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30" + [[package]] name = "rocksdb" version = "0.21.0" @@ -5486,6 +6165,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rstar" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73111312eb7a2287d229f06c00ff35b51ddee180f017ab6dec1f69d62ac098d6" +dependencies = [ + "heapless", + "num-traits", + "smallvec", +] + [[package]] name = "rtrb" version = "0.2.3" @@ -5519,6 +6209,16 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "rust_decimal" version = "1.34.2" @@ -5547,6 +6247,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_lexer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5" +dependencies = [ + "unicode-xid", +] + [[package]] name = "rustc_version" version = "0.2.3" @@ -5741,6 +6450,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ + "password-hash", "pbkdf2 0.12.2", "salsa20", "sha2", @@ -5823,6 +6533,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.196" @@ -5903,7 +6619,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ "serde", - "serde_with_macros", + "serde_with_macros 1.5.2", +] + +[[package]] +name = "serde_with" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a" +dependencies = [ + "base64 0.21.7", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.2", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros 3.7.0", + "time", ] [[package]] @@ -5918,6 +6652,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serde_with_macros" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" +dependencies = [ + "darling 0.20.5", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "sha-1" version = "0.10.1" @@ -6083,6 +6829,43 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +[[package]] +name = "smol_str" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" +dependencies = [ + "serde", +] + +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + [[package]] name = "socket2" version = "0.4.10" @@ -6103,6 +6886,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spade" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61addf9117b11d1f5b4bf6fe94242ba25f59d2d4b2080544b771bd647024fd00" +dependencies = [ + "hashbrown 0.14.3", + "num-traits", + "robust", + "smallvec", +] + [[package]] name = "spin" version = "0.5.2" @@ -6181,12 +6976,50 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "storekey" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c42833834a5d23b344f71d87114e0cc9994766a5c42938f4b50e7b2aef85b2" +dependencies = [ + "byteorder", + "memchr", + "serde", + "thiserror", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.1", + "phf_shared 0.10.0", + "precomputed-hash", +] + [[package]] name = "stringprep" version = "0.1.4" @@ -6237,6 +7070,143 @@ dependencies = [ "thiserror", ] +[[package]] +name = "surrealdb" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427e35b7b49c42e8e5a5de5621af3a953cce6221fff06d089cbe1920dc6fb39b" +dependencies = [ + "async-channel 1.9.0", + "bincode", + "chrono", + "dmp", + "flume", + "futures", + "futures-concurrency", + "geo 0.27.0", + "indexmap 2.2.2", + "once_cell", + "path-clean", + "pharos", + "reqwest", + "revision", + "ring 0.17.7", + "rust_decimal", + "rustls", + "semver 1.0.21", + "serde", + "serde_json", + "surrealdb-core", + "thiserror", + "tokio", + "tokio-tungstenite", + "tokio-util", + "tracing", + "trice", + "url", + "uuid", + "wasm-bindgen-futures", + "wasmtimer", + "ws_stream_wasm", +] + +[[package]] +name = "surrealdb-core" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b66c830b767da9b8a289877b2ea3c290b6a56482ae604848b977446cdcdda6" +dependencies = [ + "addr", + "any_ascii", + "argon2", + "async-channel 1.9.0", + "async-executor", + "async-recursion 1.0.5", + "base64 0.21.7", + "bcrypt", + "bincode", + "bytes", + "cedar-policy", + "chrono", + "deunicode", + "dmp", + "fst", + "futures", + "fuzzy-matcher", + "geo 0.27.0", + "geo-types", + "hex", + "ipnet", + "lexicmp", + "md-5", + "nanoid", + "nom", + "num_cpus", + "object_store", + "once_cell", + "pbkdf2 0.12.2", + "pharos", + "pin-project-lite", + "quick_cache", + "radix_trie", + "rand 0.8.5", + "regex", + "revision", + "ring 0.17.7", + "roaring", + "rust-stemmers", + "rust_decimal", + "scrypt", + "semver 1.0.21", + "serde", + "serde_json", + "sha1", + "sha2", + "snap", + "storekey", + "surrealdb-derive", + "surrealdb-jsonwebtoken", + "thiserror", + "tokio", + "tracing", + "trice", + "ulid", + "url", + "uuid", + "wasm-bindgen-futures", + "wasmtimer", + "ws_stream_wasm", +] + +[[package]] +name = "surrealdb-derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacdb4c58b9ebef0291310afcd63af0012d85610d361f3785952c61b6f1dddf4" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "surrealdb-jsonwebtoken" +version = "8.3.0-surreal.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d4f759c65df8a8cf2d83c99db7fdd3ae5b8fff05fa7fe69a8612f29dd5f99b" +dependencies = [ + "base64 0.21.7", + "getrandom 0.2.12", + "hmac", + "pem 2.0.1", + "rand 0.8.5", + "ring 0.16.20", + "rsa", + "serde", + "serde_json", + "sha2", + "simple_asn1", +] + [[package]] name = "syn" version = "1.0.109" @@ -6329,6 +7299,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -6603,6 +7584,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.25.4", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -6799,6 +7795,17 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "trice" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3aaab10ae9fac0b10f392752bf56f0fd20845f39037fec931e8537b105b515a" +dependencies = [ + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "triomphe" version = "0.1.11" @@ -6867,6 +7874,26 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb1626d07cb5c1bb2cf17d94c0be4852e8a7c02b041acec9a8c5bdda99f9d580" +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 0.2.11", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "twox-hash" version = "1.6.3" @@ -6895,6 +7922,18 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ulid" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34778c17965aa2a08913b57e1f34db9b4a63f5de31768b55bf20d2795f921259" +dependencies = [ + "getrandom 0.2.12", + "rand 0.8.5", + "serde", + "web-time", +] + [[package]] name = "unicase" version = "2.7.0" @@ -6925,12 +7964,34 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-script" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" + +[[package]] +name = "unicode-security" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee9e13753df674873f3c4693b240ae5c03245ddc157dfccf7c26db9329af3a11" +dependencies = [ + "unicode-normalization", + "unicode-script", +] + [[package]] name = "unicode-width" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "unsigned-varint" version = "0.7.2" @@ -6992,6 +8053,12 @@ dependencies = [ "libc", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.1" @@ -7004,8 +8071,10 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ + "atomic", "getrandom 0.2.12", "serde", + "wasm-bindgen", ] [[package]] @@ -7189,6 +8258,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "wasm-bindgen", +] + [[package]] name = "weak-table" version = "0.3.2" @@ -7575,6 +8657,25 @@ dependencies = [ "tokio", ] +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.0", + "send_wrapper", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/core/Cargo.toml b/core/Cargo.toml index f59a25ab3b55..696288e634c4 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -183,7 +183,7 @@ services-wasabi = [] services-webdav = [] services-webhdfs = [] services-yandex-disk = [] - +services-surrealdb = ["dep:surrealdb"] [lib] bench = false @@ -317,6 +317,8 @@ suppaftp = { version = "5.3.1", default-features = false, features = [ tikv-client = { version = "0.3.0", optional = true, default-features = false } # for services-hdfs-native hdfs-native = { version = "0.6.0", optional = true } +# for services-surrealdb +surrealdb = { version = "1.3.0", optional = true, features = ["protocol-http"] } # Layers # for layers-async-backtrace diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index 780dab54f4d0..1cdb39f01a33 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -397,3 +397,10 @@ mod vercel_blob; pub use vercel_blob::VercelBlob; #[cfg(feature = "services-vercel-blob")] pub use vercel_blob::VercelBlobConfig; + +#[cfg(feature = "services-surrealdb")] +mod surrealdb; +#[cfg(feature = "services-surrealdb")] +pub use surrealdb::Surrealdb; +#[cfg(feature = "services-surrealdb")] +pub use surrealdb::SurrealdbConfig; diff --git a/core/src/services/surrealdb/backend.rs b/core/src/services/surrealdb/backend.rs new file mode 100644 index 000000000000..6ba077b49e63 --- /dev/null +++ b/core/src/services/surrealdb/backend.rs @@ -0,0 +1,393 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use std::collections::HashMap; +use std::fmt::{Debug, Formatter}; +use std::sync::Arc; + +use async_trait::async_trait; +use serde::Deserialize; +use surrealdb::engine::any::Any; +use surrealdb::opt::auth::Database; +use surrealdb::Surreal; +use tokio::sync::OnceCell; + +use crate::raw::adapters::kv; +use crate::raw::{normalize_root, ConfigDeserializer}; +use crate::{Builder, Capability, Error, ErrorKind, Scheme}; + +/// Config for Surrealdb services support. +#[derive(Default, Deserialize)] +#[serde(default)] +#[non_exhaustive] +pub struct SurrealdbConfig { + connection_string: Option, + username: Option, + password: Option, + namespace: Option, + database: Option, + table: Option, + key_field: Option, + value_field: Option, + root: Option, +} + +impl Debug for SurrealdbConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut d = f.debug_struct("SurrealdbConfig"); + + d.field("connection_string", &self.connection_string) + .field("username", &self.username) + .field("password", &"") + .field("namespace", &self.namespace) + .field("database", &self.database) + .field("table", &self.table) + .field("key_field", &self.key_field) + .field("value_field", &self.value_field) + .field("root", &self.root) + .finish() + } +} +#[doc = include_str!("docs.md")] +#[derive(Default)] +pub struct SurrealdbBuilder { + config: SurrealdbConfig, +} + +impl Debug for SurrealdbBuilder { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SurrealdbBuilder") + .field("config", &self.config) + .finish() + } +} + +impl SurrealdbBuilder { + /// Set the connection_string of the surrealdb service. + /// + /// This connection string is used to connect to the surrealdb service. There are url based formats: + /// + /// ## Url + /// + /// - `ws://ip:port` + /// - `wss://ip:port` + /// - `http://ip:port` + /// - `https://ip:port` + /// + pub fn connection_string(&mut self, connection_string: &str) -> &mut Self { + if !connection_string.is_empty() { + self.config.connection_string = Some(connection_string.to_string()); + } + self + } + + /// set the working directory, all operations will be performed under it. + /// + /// default: "/" + pub fn root(&mut self, root: &str) -> &mut Self { + if !root.is_empty() { + self.config.root = Some(root.to_string()); + } + self + } + + /// Set the table name of the surrealdb service for read/write. + pub fn table(&mut self, table: &str) -> &mut Self { + if !table.is_empty() { + self.config.table = Some(table.to_string()); + } + self + } + + /// Set the username of the surrealdb service for signin. + pub fn username(&mut self, username: &str) -> &mut Self { + if !username.is_empty() { + self.config.username = Some(username.to_string()); + } + self + } + + /// Set the password of the surrealdb service for signin. + pub fn password(&mut self, password: &str) -> &mut Self { + if !password.is_empty() { + self.config.password = Some(password.to_string()); + } + self + } + + /// Set the namespace of the surrealdb service for read/write. + pub fn namespace(&mut self, namespace: &str) -> &mut Self { + if !namespace.is_empty() { + self.config.namespace = Some(namespace.to_string()); + } + self + } + + /// Set the database of the surrealdb service for read/write. + pub fn database(&mut self, database: &str) -> &mut Self { + if !database.is_empty() { + self.config.database = Some(database.to_string()); + } + self + } + + /// Set the key field name of the surrealdb service for read/write. + /// + /// Default to `key` if not specified. + pub fn key_field(&mut self, key_field: &str) -> &mut Self { + if !key_field.is_empty() { + self.config.key_field = Some(key_field.to_string()); + } + self + } + + /// Set the value field name of the surrealdb service for read/write. + /// + /// Default to `value` if not specified. + pub fn value_field(&mut self, value_field: &str) -> &mut Self { + if !value_field.is_empty() { + self.config.value_field = Some(value_field.to_string()); + } + self + } +} + +impl Builder for SurrealdbBuilder { + const SCHEME: Scheme = Scheme::Surrealdb; + type Accessor = SurrealdbBackend; + + fn from_map(map: HashMap) -> Self { + let config = SurrealdbConfig::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"); + + SurrealdbBuilder { config } + } + + fn build(&mut self) -> crate::Result { + let connection_string = match self.config.connection_string.clone() { + Some(v) => v, + None => { + return Err( + Error::new(ErrorKind::ConfigInvalid, "connection_string is empty") + .with_context("service", Scheme::Surrealdb), + ) + } + }; + + let namespace = match self.config.namespace.clone() { + Some(v) => v, + None => { + return Err(Error::new(ErrorKind::ConfigInvalid, "namespace is empty") + .with_context("service", Scheme::Surrealdb)) + } + }; + let database = match self.config.database.clone() { + Some(v) => v, + None => { + return Err(Error::new(ErrorKind::ConfigInvalid, "database is empty") + .with_context("service", Scheme::Surrealdb)) + } + }; + let table = match self.config.table.clone() { + Some(v) => v, + None => { + return Err(Error::new(ErrorKind::ConfigInvalid, "table is empty") + .with_context("service", Scheme::Surrealdb)) + } + }; + + let username = self.config.username.clone().unwrap_or_default(); + let password = self.config.password.clone().unwrap_or_default(); + let key_field = self + .config + .key_field + .clone() + .unwrap_or_else(|| "key".to_string()); + let value_field = self + .config + .value_field + .clone() + .unwrap_or_else(|| "value".to_string()); + let root = normalize_root( + self.config + .root + .clone() + .unwrap_or_else(|| "/".to_string()) + .as_str(), + ); + + Ok(SurrealdbBackend::new(Adapter { + db: OnceCell::new(), + connection_string, + username, + password, + namespace, + database, + table, + key_field, + value_field, + }) + .with_root(&root)) + } +} + +/// Backend for Surrealdb service +pub type SurrealdbBackend = kv::Backend; + +#[derive(Clone)] +pub struct Adapter { + db: OnceCell>>, + connection_string: String, + + username: String, + password: String, + namespace: String, + database: String, + + table: String, + key_field: String, + value_field: String, +} + +impl Debug for Adapter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Adapter") + .field("connection_string", &self.connection_string) + .field("username", &self.username) + .field("password", &"") + .field("namespace", &self.namespace) + .field("database", &self.database) + .field("table", &self.table) + .field("key_field", &self.key_field) + .field("value_field", &self.value_field) + .finish() + } +} + +impl Adapter { + async fn get_connection(&self) -> crate::Result<&Surreal> { + self.db + .get_or_try_init(|| async { + let namespace = self.namespace.as_str(); + let database = self.database.as_str(); + + let db: Surreal = Surreal::init(); + db.connect(self.connection_string.clone()) + .await + .map_err(parse_surrealdb_error)?; + + if !self.username.is_empty() && !self.password.is_empty() { + db.signin(Database { + namespace, + database, + username: self.username.as_str(), + password: self.password.as_str(), + }) + .await + .map_err(parse_surrealdb_error)?; + } + db.use_ns(namespace) + .use_db(database) + .await + .map_err(parse_surrealdb_error)?; + + Ok(Arc::new(db)) + }) + .await + .map(|v| v.as_ref()) + } +} +#[async_trait] +impl kv::Adapter for Adapter { + fn metadata(&self) -> kv::Metadata { + kv::Metadata::new( + Scheme::Surrealdb, + &self.table, + Capability { + read: true, + write: true, + ..Default::default() + }, + ) + } + + async fn get(&self, path: &str) -> crate::Result>> { + let query: String = if self.key_field == "id" { + "SELECT type::field($value_field) FROM type::thing($table, $path)".to_string() + } else { + format!("SELECT type::field($value_field) FROM type::table($table) WHERE {} = $path LIMIT 1", self.key_field) + }; + + let mut result = self + .get_connection() + .await? + .query(query) + .bind(("namespace", "opendal")) + .bind(("path", path)) + .bind(("table", self.table.as_str())) + .bind(("value_field", self.value_field.as_str())) + .await + .map_err(parse_surrealdb_error)?; + + let value: Option> = result + .take((0, self.value_field.as_str())) + .map_err(parse_surrealdb_error)?; + + Ok(value) + } + + async fn set(&self, path: &str, value: &[u8]) -> crate::Result<()> { + let query = format!( + "INSERT INTO {} ({}, {}) \ + VALUES ($path, $value) \ + ON DUPLICATE KEY UPDATE {} = $value", + self.table, self.key_field, self.value_field, self.value_field + ); + self.get_connection() + .await? + .query(query) + .bind(("path", path)) + .bind(("value", value)) + .await + .map_err(parse_surrealdb_error)?; + Ok(()) + } + + async fn delete(&self, path: &str) -> crate::Result<()> { + let query: String = if self.key_field == "id" { + "DELETE FROM type::thing($table, $path)".to_string() + } else { + format!( + "DELETE FROM type::table($table) WHERE {} = $path", + self.key_field + ) + }; + + self.get_connection() + .await? + .query(query.as_str()) + .bind(("path", path)) + .bind(("table", self.table.as_str())) + .await + .map_err(parse_surrealdb_error)?; + Ok(()) + } +} + +fn parse_surrealdb_error(err: surrealdb::Error) -> Error { + Error::new(ErrorKind::Unexpected, "unhandled error from surrealdb").set_source(err) +} diff --git a/core/src/services/surrealdb/docs.md b/core/src/services/surrealdb/docs.md new file mode 100644 index 000000000000..8b2fbc4ae926 --- /dev/null +++ b/core/src/services/surrealdb/docs.md @@ -0,0 +1,55 @@ +## Capabilities + +This service can be used to: + +- [x] stat +- [x] read +- [x] write +- [ ] create_dir +- [x] delete +- [ ] copy +- [ ] rename +- [ ] ~~list~~ +- [ ] scan +- [ ] ~~presign~~ +- [ ] blocking + +## Configuration + +- `root`: Set the working directory of `OpenDAL` +- `connection_string`: Set the connection string of surrealdb server +- `username`: set the username of surrealdb +- `password`: set the password of surrealdb +- `namespace`: set the namespace of surrealdb +- `database`: set the database of surrealdb +- `table`: Set the table of surrealdb +- `key_field`: Set the key field of surrealdb +- `value_field`: Set the value field of surrealdb +- + +## Example + +### Via Builder + +```rust +use anyhow::Result; +use opendal::services::Surrealdb; +use opendal::Operator; + +#[tokio::main] +async fn main() -> Result<()> { + let mut builder = Surrealdb::default(); + builder.root("/"); + builder.connection_string("ws://127.0.0.1:8000"); + builder.username("username"); + builder.password("password"); + builder.namespace("namespace"); + builder.database("database"); + builder.table("table"); + builder.key_field("key"); + builder.value_field("value"); + + let op = Operator::new(builder)?.finish(); + Ok(()) +} +``` diff --git a/core/src/services/surrealdb/mod.rs b/core/src/services/surrealdb/mod.rs new file mode 100644 index 000000000000..0f5d19b38f0b --- /dev/null +++ b/core/src/services/surrealdb/mod.rs @@ -0,0 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +mod backend; +pub use backend::SurrealdbBuilder as Surrealdb; +pub use backend::SurrealdbConfig; diff --git a/core/src/types/scheme.rs b/core/src/types/scheme.rs index 1e7918729c50..b5b03e44f278 100644 --- a/core/src/types/scheme.rs +++ b/core/src/types/scheme.rs @@ -155,6 +155,8 @@ pub enum Scheme { Github, /// [Native HDFS](crate::services::hdfs_native): Hdfs Native service, using rust hdfs-native client for hdfs HdfsNative, + /// [surrealdb](crate::services::surrealdb): Surrealdb Services + Surrealdb, /// Custom that allow users to implement services outside of OpenDAL. /// /// # NOTE @@ -295,6 +297,8 @@ impl Scheme { Scheme::Mongodb, #[cfg(feature = "services-hdfs-native")] Scheme::HdfsNative, + #[cfg(feature = "services-surrealdb")] + Scheme::Surrealdb, ]) } } @@ -381,6 +385,7 @@ impl FromStr for Scheme { "azfile" => Ok(Scheme::Azfile), "mongodb" => Ok(Scheme::Mongodb), "hdfs_native" => Ok(Scheme::HdfsNative), + "surrealdb" => Ok(Scheme::Surrealdb), _ => Ok(Scheme::Custom(Box::leak(s.into_boxed_str()))), } } @@ -450,6 +455,7 @@ impl From for &'static str { Scheme::YandexDisk => "yandex_disk", Scheme::Pcloud => "pcloud", Scheme::HdfsNative => "hdfs_native", + Scheme::Surrealdb => "surrealdb", Scheme::Custom(v) => v, } }