From 6132b136518a1a086d509a0257a1572725109b1b Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Wed, 20 Mar 2024 15:51:03 -0400 Subject: [PATCH 01/66] scaffolding for rust server --- packages/duckdb-server-rust/.gitignore | 1 + packages/duckdb-server-rust/Cargo.lock | 2201 +++++++++++++++++++++++ packages/duckdb-server-rust/Cargo.toml | 11 + packages/duckdb-server-rust/src/main.rs | 27 + 4 files changed, 2240 insertions(+) create mode 100644 packages/duckdb-server-rust/.gitignore create mode 100644 packages/duckdb-server-rust/Cargo.lock create mode 100644 packages/duckdb-server-rust/Cargo.toml create mode 100644 packages/duckdb-server-rust/src/main.rs diff --git a/packages/duckdb-server-rust/.gitignore b/packages/duckdb-server-rust/.gitignore new file mode 100644 index 000000000..2f7896d1d --- /dev/null +++ b/packages/duckdb-server-rust/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock new file mode 100644 index 000000000..febce03bb --- /dev/null +++ b/packages/duckdb-server-rust/Cargo.lock @@ -0,0 +1,2201 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "const-random", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "arrow" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc25126d18a012146a888a0298f2c22e1150327bd2765fc76d710a556b2d614" +dependencies = [ + "ahash 0.8.11", + "arrow-arith", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-ord", + "arrow-row", + "arrow-schema", + "arrow-select", + "arrow-string", +] + +[[package]] +name = "arrow-arith" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ccd45e217ffa6e53bbb0080990e77113bdd4e91ddb84e97b77649810bcf1a7" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "num", +] + +[[package]] +name = "arrow-array" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bda9acea48b25123c08340f3a8ac361aa0f74469bb36f5ee9acf923fce23e9d" +dependencies = [ + "ahash 0.8.11", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "hashbrown 0.14.3", + "num", +] + +[[package]] +name = "arrow-buffer" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a0fc21915b00fc6c2667b069c1b64bdd920982f426079bc4a7cab86822886c" +dependencies = [ + "bytes", + "half", + "num", +] + +[[package]] +name = "arrow-cast" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dc0368ed618d509636c1e3cc20db1281148190a78f43519487b2daf07b63b4a" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "base64", + "chrono", + "comfy-table", + "half", + "lexical-core", + "num", +] + +[[package]] +name = "arrow-data" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907fafe280a3874474678c1858b9ca4cb7fd83fb8034ff5b6d6376205a08c634" +dependencies = [ + "arrow-buffer", + "arrow-schema", + "half", + "num", +] + +[[package]] +name = "arrow-ord" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b23b0e53c0db57c6749997fd343d4c0354c994be7eca67152dd2bdb9a3e1bb4" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "half", + "num", +] + +[[package]] +name = "arrow-row" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361249898d2d6d4a6eeb7484be6ac74977e48da12a4dd81a708d620cc558117a" +dependencies = [ + "ahash 0.8.11", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "half", + "hashbrown 0.14.3", +] + +[[package]] +name = "arrow-schema" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e28a5e781bf1b0f981333684ad13f5901f4cd2f20589eab7cf1797da8fc167" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "arrow-select" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f6208466590960efc1d2a7172bc4ff18a67d6e25c529381d7f96ddaf0dc4036" +dependencies = [ + "ahash 0.8.11", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num", +] + +[[package]] +name = "arrow-string" +version = "49.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a48149c63c11c9ff571e50ab8f017d2a7cb71037a882b42f6354ed2da9acc7" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "num", + "regex", + "regex-syntax", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.53", + "syn_derive", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.4", +] + +[[package]] +name = "comfy-table" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +dependencies = [ + "strum", + "strum_macros", + "unicode-width", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "duckdb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91064bc413bb2db36005516878ab585da67e9b093956e1af1b6e036a2a9cfa4f" +dependencies = [ + "arrow", + "cast", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libduckdb-sys", + "memchr", + "rust_decimal", + "smallvec", + "strum", +] + +[[package]] +name = "duckdb-server-rust" +version = "0.1.0" +dependencies = [ + "duckdb", + "tokio", + "warp", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lexical-core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" +dependencies = [ + "lexical-parse-integer", + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-parse-integer" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-util" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lexical-write-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" +dependencies = [ + "lexical-util", + "lexical-write-integer", + "static_assertions", +] + +[[package]] +name = "lexical-write-integer" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libduckdb-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "472e81a731bd70f22d81968fca6fb95bcce6ef5bda7e48b09574d41a6fda726b" +dependencies = [ + "autocfg", + "flate2", + "pkg-config", + "serde", + "serde_json", + "tar", + "vcpkg", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "mime" +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 = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.53", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "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", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[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", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multer", + "percent-encoding", + "pin-project", + "rustls-pemfile", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.53", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml new file mode 100644 index 000000000..a0dac14a1 --- /dev/null +++ b/packages/duckdb-server-rust/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "duckdb-server-rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +duckdb = "0.10.1" +tokio = { version = "1", features = ["full"] } +warp = "0.3" diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs new file mode 100644 index 000000000..1094f0987 --- /dev/null +++ b/packages/duckdb-server-rust/src/main.rs @@ -0,0 +1,27 @@ +use warp::Filter; +// use duckdb::{params, Connection, Result}; +use warp::http::header::{HeaderMap, HeaderValue}; +use warp::reply::Json; + +#[tokio::main] +async fn main() { + let mut headers = HeaderMap::new(); + headers.insert("Access-Control-Allow-Origin", HeaderValue::from_static("*")); + + // let conn = Connection::open_in_memory()?; + + fn query() -> Json { + let our_ids = vec![1, 3, 7, 13]; + warp::reply::json(&our_ids) + } + + let server = warp::any() + .map(query) + .with(warp::reply::with::headers(headers)); + + println!("Listening on http://localhost:3030"); + + warp::serve(server) + .run(([127, 0, 0, 1], 3030)) + .await; +} From e13550d13fec97719e812cdfe1f8a84604aa3dc6 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 11 Jun 2024 23:05:38 -0400 Subject: [PATCH 02/66] update deps --- packages/duckdb-server-rust/Cargo.lock | 830 +++++++++++++++++-------- packages/duckdb-server-rust/Cargo.toml | 2 +- 2 files changed, 558 insertions(+), 274 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index febce03bb..b9d670e00 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -53,9 +53,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -80,11 +80,10 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "arrow" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc25126d18a012146a888a0298f2c22e1150327bd2765fc76d710a556b2d614" +checksum = "219d05930b81663fd3b32e3bde8ce5bff3c4d23052a99f11a8fa50a3b47b2658" dependencies = [ - "ahash 0.8.11", "arrow-arith", "arrow-array", "arrow-buffer", @@ -99,9 +98,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ccd45e217ffa6e53bbb0080990e77113bdd4e91ddb84e97b77649810bcf1a7" +checksum = "0272150200c07a86a390be651abdd320a2d12e84535f0837566ca87ecd8f95e0" dependencies = [ "arrow-array", "arrow-buffer", @@ -114,9 +113,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bda9acea48b25123c08340f3a8ac361aa0f74469bb36f5ee9acf923fce23e9d" +checksum = "8010572cf8c745e242d1b632bd97bd6d4f40fefed5ed1290a8f433abaa686fea" dependencies = [ "ahash 0.8.11", "arrow-buffer", @@ -124,15 +123,15 @@ dependencies = [ "arrow-schema", "chrono", "half", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "num", ] [[package]] name = "arrow-buffer" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a0fc21915b00fc6c2667b069c1b64bdd920982f426079bc4a7cab86822886c" +checksum = "0d0a2432f0cba5692bf4cb757469c66791394bac9ec7ce63c1afe74744c37b27" dependencies = [ "bytes", "half", @@ -141,28 +140,30 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc0368ed618d509636c1e3cc20db1281148190a78f43519487b2daf07b63b4a" +checksum = "9abc10cd7995e83505cc290df9384d6e5412b207b79ce6bdff89a10505ed2cba" dependencies = [ "arrow-array", "arrow-buffer", "arrow-data", "arrow-schema", "arrow-select", - "base64", + "atoi", + "base64 0.22.1", "chrono", "comfy-table", "half", "lexical-core", "num", + "ryu", ] [[package]] name = "arrow-data" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907fafe280a3874474678c1858b9ca4cb7fd83fb8034ff5b6d6376205a08c634" +checksum = "2742ac1f6650696ab08c88f6dd3f0eb68ce10f8c253958a18c943a68cd04aec5" dependencies = [ "arrow-buffer", "arrow-schema", @@ -172,9 +173,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b23b0e53c0db57c6749997fd343d4c0354c994be7eca67152dd2bdb9a3e1bb4" +checksum = "e3e6b61e3dc468f503181dccc2fc705bdcc5f2f146755fa5b56d0a6c5943f412" dependencies = [ "arrow-array", "arrow-buffer", @@ -187,9 +188,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361249898d2d6d4a6eeb7484be6ac74977e48da12a4dd81a708d620cc558117a" +checksum = "848ee52bb92eb459b811fb471175ea3afcf620157674c8794f539838920f9228" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -197,23 +198,23 @@ dependencies = [ "arrow-data", "arrow-schema", "half", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] name = "arrow-schema" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09e28a5e781bf1b0f981333684ad13f5901f4cd2f20589eab7cf1797da8fc167" +checksum = "02d9483aaabe910c4781153ae1b6ae0393f72d9ef757d38d09d450070cf2e528" dependencies = [ "bitflags 2.5.0", ] [[package]] name = "arrow-select" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f6208466590960efc1d2a7172bc4ff18a67d6e25c529381d7f96ddaf0dc4036" +checksum = "849524fa70e0e3c5ab58394c770cb8f514d0122d20de08475f7b472ed8075830" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -225,31 +226,41 @@ dependencies = [ [[package]] name = "arrow-string" -version = "49.0.0" +version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a48149c63c11c9ff571e50ab8f017d2a7cb71037a882b42f6354ed2da9acc7" +checksum = "9373cb5a021aee58863498c37eb484998ef13377f69989c6c5ccfbd258236cdb" dependencies = [ "arrow-array", "arrow-buffer", "arrow-data", "arrow-schema", "arrow-select", + "memchr", "num", "regex", "regex-syntax", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -266,6 +277,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -301,9 +318,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" dependencies = [ "borsh-derive", "cfg_aliases", @@ -311,23 +328,23 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", "syn_derive", ] [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" @@ -359,9 +376,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cast" @@ -371,9 +388,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -383,30 +400,30 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum", - "strum_macros", + "strum 0.26.2", + "strum_macros 0.26.4", "unicode-width", ] @@ -447,9 +464,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -472,9 +489,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "digest" @@ -486,11 +503,22 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "duckdb" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91064bc413bb2db36005516878ab585da67e9b093956e1af1b6e036a2a9cfa4f" +checksum = "424ede399a5d1084e65c0888fda71e407e5809400c92ff2cf510bfd1697b9c76" dependencies = [ "arrow", "cast", @@ -501,7 +529,7 @@ dependencies = [ "memchr", "rust_decimal", "smallvec", - "strum", + "strum 0.25.0", ] [[package]] @@ -515,9 +543,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -530,9 +558,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -558,15 +586,15 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -647,9 +675,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -658,22 +686,22 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -683,9 +711,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ "cfg-if", "crunchy", @@ -703,9 +731,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -717,7 +745,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -726,10 +754,10 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "headers-core", - "http", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -741,7 +769,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http", + "http 0.2.12", ] [[package]] @@ -750,6 +778,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -767,6 +801,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -774,15 +819,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" [[package]] name = "httpdate" @@ -792,16 +837,16 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", + "http 0.2.12", "http-body", "httparse", "httpdate", @@ -837,31 +882,151 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -938,15 +1103,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libduckdb-sys" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "472e81a731bd70f22d81968fca6fb95bcce6ef5bda7e48b09574d41a6fda726b" +checksum = "51b3f02cecc430f61561bde538d42af4be2d9d5a8b058f74883e460bc1055461" dependencies = [ "autocfg", "flate2", @@ -965,15 +1130,21 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -987,9 +1158,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1009,9 +1180,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -1036,7 +1207,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.12", "httparse", "log", "memchr", @@ -1047,9 +1218,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -1061,20 +1232,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -1090,9 +1260,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -1101,11 +1271,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -1113,9 +1282,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -1133,9 +1302,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -1148,9 +1317,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1158,15 +1327,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -1192,14 +1361,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1253,9 +1422,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -1282,9 +1451,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1334,11 +1503,20 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1348,9 +1526,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1359,9 +1537,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rend" @@ -1403,9 +1581,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.34.3" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", @@ -1419,15 +1597,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -1436,26 +1614,17 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64", -] - [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "scoped-tls" @@ -1477,29 +1646,29 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1531,9 +1700,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1555,15 +1724,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1575,6 +1744,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1587,20 +1762,39 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros", + "strum_macros 0.25.3", ] +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" + [[package]] name = "strum_macros" version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.53", + "syn 2.0.66", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", ] [[package]] @@ -1616,9 +1810,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -1634,7 +1828,18 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] @@ -1645,9 +1850,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", @@ -1656,22 +1861,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", ] [[package]] @@ -1683,6 +1888,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1700,9 +1915,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -1719,31 +1934,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", + "syn 2.0.66", ] [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", @@ -1753,23 +1957,22 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" @@ -1816,14 +2019,14 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.1.0", "httparse", "log", "rand", @@ -1848,38 +2051,23 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "url" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", @@ -1892,6 +2080,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.8.0" @@ -1921,15 +2121,15 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" dependencies = [ "bytes", "futures-channel", "futures-util", "headers", - "http", + "http 0.2.12", "hyper", "log", "mime", @@ -1937,13 +2137,11 @@ dependencies = [ "multer", "percent-encoding", "pin-project", - "rustls-pemfile", "scoped-tls", "serde", "serde_json", "serde_urlencoded", "tokio", - "tokio-stream", "tokio-tungstenite", "tokio-util", "tower-service", @@ -1977,7 +2175,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -1999,7 +2197,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2016,7 +2214,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2034,7 +2232,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2054,17 +2252,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -2075,9 +2274,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -2087,9 +2286,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -2099,9 +2298,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -2111,9 +2316,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -2123,9 +2328,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -2135,9 +2340,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -2147,9 +2352,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -2160,6 +2365,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -2180,22 +2397,89 @@ dependencies = [ "rustix", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.66", ] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index a0dac14a1..89720a1ba 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -6,6 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -duckdb = "0.10.1" +duckdb = "0.10.2" tokio = { version = "1", features = ["full"] } warp = "0.3" From aaf30442e11e4efc9fffb56e18caca44392af53c Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 14:51:57 -0400 Subject: [PATCH 03/66] basic duckdb server --- packages/duckdb-server-rust/Cargo.lock | 1173 +++++++++++++---------- packages/duckdb-server-rust/Cargo.toml | 14 +- packages/duckdb-server-rust/Readme.md | 19 + packages/duckdb-server-rust/src/main.rs | 273 +++++- 4 files changed, 971 insertions(+), 508 deletions(-) create mode 100644 packages/duckdb-server-rust/Readme.md diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index b9d670e00..7ada2aed8 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -72,6 +72,18 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayvec" version = "0.7.4" @@ -88,7 +100,10 @@ dependencies = [ "arrow-array", "arrow-buffer", "arrow-cast", + "arrow-csv", "arrow-data", + "arrow-ipc", + "arrow-json", "arrow-ord", "arrow-row", "arrow-schema", @@ -159,6 +174,25 @@ dependencies = [ "ryu", ] +[[package]] +name = "arrow-csv" +version = "51.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cbcba196b862270bf2a5edb75927380a7f3a163622c61d40cbba416a6305f2" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "chrono", + "csv", + "csv-core", + "lazy_static", + "lexical-core", + "regex", +] + [[package]] name = "arrow-data" version = "51.0.0" @@ -171,6 +205,40 @@ dependencies = [ "num", ] +[[package]] +name = "arrow-ipc" +version = "51.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a42ea853130f7e78b9b9d178cb4cd01dee0f78e64d96c2949dc0a915d6d9e19d" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "flatbuffers", +] + +[[package]] +name = "arrow-json" +version = "51.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaafb5714d4e59feae964714d724f880511500e3569cc2a94d02456b403a2a49" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "indexmap", + "lexical-core", + "num", + "serde", + "serde_json", +] + [[package]] name = "arrow-ord" version = "51.0.0" @@ -207,7 +275,7 @@ version = "51.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d9483aaabe910c4781153ae1b6ae0393f72d9ef757d38d09d450070cf2e528" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -238,7 +306,18 @@ dependencies = [ "memchr", "num", "regex", - "regex-syntax", + "regex-syntax 0.8.4", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", ] [[package]] @@ -250,17 +329,104 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core", + "base64 0.21.7", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper 1.0.1", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-server" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ad46c3ec4e12f4a4b6835e173ba21c25e484c9d02b49770bf006ce5367c036" +dependencies = [ + "arc-swap", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tower", + "tower-service", +] + [[package]] name = "backtrace" -version = "0.3.72" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -291,9 +457,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -336,7 +502,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "syn_derive", ] @@ -388,9 +554,14 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.99" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] [[package]] name = "cfg-if" @@ -413,7 +584,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -422,7 +593,7 @@ version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum 0.26.2", + "strum 0.26.3", "strum_macros 0.26.4", "unicode-width", ] @@ -487,6 +658,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -503,17 +695,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "duckdb" version = "0.10.2" @@ -522,6 +703,7 @@ checksum = "424ede399a5d1084e65c0888fda71e407e5809400c92ff2cf510bfd1697b9c76" dependencies = [ "arrow", "cast", + "csv", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -530,24 +712,26 @@ dependencies = [ "rust_decimal", "smallvec", "strum 0.25.0", + "url", ] [[package]] name = "duckdb-server-rust" version = "0.1.0" dependencies = [ + "anyhow", + "arrow", + "axum", + "axum-server", "duckdb", + "listenfd", + "lru", + "serde", + "serde_json", "tokio", - "warp", -] - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", + "tower-http", + "tracing", + "tracing-subscriber", ] [[package]] @@ -590,6 +774,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "flatbuffers" +version = "23.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" +dependencies = [ + "bitflags 1.3.2", + "rustc_version", +] + [[package]] name = "flate2" version = "1.0.30" @@ -628,7 +822,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -692,16 +885,16 @@ checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" -version = "0.3.26" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", - "http 0.2.12", + "http", "indexmap", "slab", "tokio", @@ -729,6 +922,15 @@ dependencies = [ "ahash 0.7.8", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -748,30 +950,6 @@ dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http 0.2.12", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http 0.2.12", -] - [[package]] name = "heck" version = "0.4.1" @@ -792,9 +970,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -802,32 +980,33 @@ dependencies = [ ] [[package]] -name = "http" -version = "1.1.0" +name = "http-body" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "fnv", - "itoa", + "http", ] [[package]] -name = "http-body" -version = "0.4.6" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "http 0.2.12", + "futures-util", + "http", + "http-body", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -837,26 +1016,37 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.29" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", - "http 0.2.12", + "http", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", "tokio", - "tower-service", - "tracing", - "want", ] [[package]] @@ -883,178 +1073,73 @@ dependencies = [ ] [[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" +name = "idna" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "icu_locid_transform" -version = "1.5.0" +name = "indexmap" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", + "equivalent", + "hashbrown 0.14.5", ] [[package]] -name = "icu_locid_transform_data" -version = "1.5.0" +name = "itoa" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "icu_normalizer" -version = "1.5.0" +name = "jobserver" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", + "libc", ] [[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.0" +name = "js-sys" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", + "wasm-bindgen", ] [[package]] -name = "icu_properties_data" +name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "icu_provider" -version = "1.5.0" +name = "lexical-core" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", ] [[package]] -name = "icu_provider_macros" -version = "1.5.0" +name = "lexical-parse-float" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "idna" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" -dependencies = [ - "icu_normalizer", - "icu_properties", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" +checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" dependencies = [ "lexical-parse-integer", "lexical-util", @@ -1114,6 +1199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b3f02cecc430f61561bde538d42af4be2d9d5a8b058f74883e460bc1055461" dependencies = [ "autocfg", + "cc", "flate2", "pkg-config", "serde", @@ -1135,10 +1221,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] -name = "litemap" -version = "0.7.3" +name = "listenfd" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "e0500463acd96259d219abb05dc57e5a076ef04b2db9a2112846929b5f174c96" +dependencies = [ + "libc", + "uuid", + "winapi", +] [[package]] name = "lock_api" @@ -1152,15 +1243,39 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -1168,21 +1283,11 @@ 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 = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -1199,21 +1304,13 @@ dependencies = [ ] [[package]] -name = "multer" -version = "2.1.0" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 0.2.12", - "httparse", - "log", - "memchr", - "mime", - "spin", - "version_check", + "overload", + "winapi", ] [[package]] @@ -1232,9 +1329,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -1302,9 +1399,9 @@ dependencies = [ [[package]] name = "object" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -1315,6 +1412,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1333,9 +1436,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1361,7 +1464,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1422,9 +1525,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1505,11 +1608,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -1520,8 +1623,17 @@ checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1532,9 +1644,15 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.4", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.4" @@ -1550,6 +1668,21 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rkyv" version = "0.7.44" @@ -1601,19 +1734,66 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -1626,24 +1806,34 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "seahash" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.203" @@ -1661,20 +1851,30 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1698,6 +1898,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1744,12 +1953,6 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -1767,9 +1970,9 @@ dependencies = [ [[package]] name = "strum" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" @@ -1781,7 +1984,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1794,7 +1997,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1810,9 +2013,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -1828,19 +2031,20 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] -name = "synstructure" -version = "0.13.1" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] name = "tap" @@ -1876,33 +2080,33 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] -name = "tiny-keccak" -version = "2.0.2" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "crunchy", + "cfg-if", + "once_cell", ] [[package]] -name = "tinystr" -version = "0.7.6" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "displaydoc", - "zerovec", + "crunchy", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22" dependencies = [ "tinyvec_macros", ] @@ -1940,7 +2144,17 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", ] [[package]] @@ -1985,6 +2199,44 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +dependencies = [ + "bitflags 2.6.0", + "bytes", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -1999,9 +2251,21 @@ checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + [[package]] name = "tracing-core" version = "0.1.32" @@ -2009,13 +2273,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] [[package]] name = "tungstenite" @@ -2026,7 +2314,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http", "httparse", "log", "rand", @@ -2043,13 +2331,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "unicase" -version = "2.7.0" +name = "unicode-bidi" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -2057,17 +2342,32 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -2081,22 +2381,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - -[[package]] -name = "utf8_iter" -version = "1.0.4" +name = "uuid" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" [[package]] -name = "uuid" -version = "1.8.0" +name = "valuable" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vcpkg" @@ -2110,44 +2404,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "warp" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "headers", - "http 0.2.12", - "hyper", - "log", - "mime", - "mime_guess", - "multer", - "percent-encoding", - "pin-project", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-tungstenite", - "tokio-util", - "tower-service", - "tracing", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2175,7 +2431,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-shared", ] @@ -2197,7 +2453,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2208,13 +2464,35 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2232,7 +2510,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2252,18 +2530,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2274,9 +2552,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2286,9 +2564,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2298,15 +2576,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2316,9 +2594,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2328,9 +2606,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2340,9 +2618,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2352,9 +2630,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -2365,18 +2643,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - [[package]] name = "wyz" version = "0.5.1" @@ -2397,89 +2663,22 @@ dependencies = [ "rustix", ] -[[package]] -name = "yoke" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "zerofrom" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - -[[package]] -name = "zerovec" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.10.2" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 89720a1ba..d8c971cb0 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -6,6 +6,16 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -duckdb = "0.10.2" +duckdb = { version = "0.10", features = ["bundled", "csv", "json", "parquet", "url", "httpfs"] } +axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing"] } +axum-server = { version = "0.6", features = ["tls-rustls"] } tokio = { version = "1", features = ["full"] } -warp = "0.3" +tower-http = { version = "0.5.0", features = ["cors"] } +listenfd = "1.0.1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +lru = "0.10" +arrow = "51.0" +anyhow = "1.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md new file mode 100644 index 000000000..381ef0e5d --- /dev/null +++ b/packages/duckdb-server-rust/Readme.md @@ -0,0 +1,19 @@ +# DuckDB Server + +## Developers + +```sh +cargo install cargo-watch systemfd +``` + +Run with + +```sh +systemfd --no-pid -s http::3000 -- cargo watch -x run +``` + +Or just (but this won't restart when the code changes) + +```sh +cargo run +``` diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 1094f0987..e0aa9a51d 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,27 +1,262 @@ -use warp::Filter; -// use duckdb::{params, Connection, Result}; -use warp::http::header::{HeaderMap, HeaderValue}; -use warp::reply::Json; +use anyhow::Result; +use arrow::{ipc::writer::FileWriter, json::ArrayWriter}; +use axum::{ + body::Bytes, + extract::{Query, State}, + http::Method, + http::StatusCode, + response::{IntoResponse, Json, Response}, + routing::get, + Router, +}; +use duckdb::{arrow::array::RecordBatch, Connection}; +use listenfd::ListenFd; +use serde::{Deserialize, Serialize}; +use std::net::{Ipv4Addr, SocketAddr}; +use std::path::Path; +use std::sync::Arc; +use std::time::Duration; +use tokio::net::TcpListener; +use tokio::sync::Mutex; +use tower_http::cors::{Any, CorsLayer}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -#[tokio::main] -async fn main() { - let mut headers = HeaderMap::new(); - headers.insert("Access-Control-Allow-Origin", HeaderValue::from_static("*")); +struct AppState { + con: Mutex, + cache: Mutex>>, +} + +#[derive(Deserialize, Serialize)] +struct QueryParams { + #[serde(rename = "type")] + query_type: String, + sql: Option, + queries: Option>, +} + +enum QueryResponse { + Json(String), + Arrow(Vec), + Empty, +} + +impl IntoResponse for QueryResponse { + fn into_response(self) -> Response { + match self { + QueryResponse::Json(value) => value.into_response(), + QueryResponse::Arrow(bytes) => ( + StatusCode::OK, + [("Content-Type", "application/octet-stream")], + Bytes::from(bytes), + ) + .into_response(), + QueryResponse::Empty => StatusCode::OK.into_response(), + } + } +} + +async fn execute(con: &Mutex, sql: &str) -> Result<()> { + let conn = con.lock().await; + conn.execute_batch(sql)?; + Ok(()) +} + +async fn get_json(con: &Mutex, sql: &str) -> Result> { + let conn = con.lock().await; + let mut stmt = conn.prepare(sql)?; + let arrow = stmt.query_arrow([])?; + + let rbs: Vec = arrow.collect(); + + let buf = Vec::new(); + let mut writer = ArrayWriter::new(buf); + for batch in rbs { + writer.write(&batch)?; + } + writer.finish()?; + let json_data = writer.into_inner(); + Ok(json_data) +} + +async fn get_arrow_bytes(con: &Mutex, sql: &str) -> Result> { + let conn = con.lock().await; + let mut stmt = conn.prepare(sql)?; + let arrow = stmt.query_arrow([])?; + let schema = arrow.get_schema(); + + let rbs: Vec = arrow.collect(); + + // Serialize RecordBatch to Arrow IPC format + let mut buffer: Vec = Vec::new(); + { + let schema_ref = schema.as_ref(); + let mut writer = FileWriter::try_new(&mut buffer, schema_ref)?; + + for batch in rbs { + writer.write(&batch)?; + } + + writer.finish()?; + } - // let conn = Connection::open_in_memory()?; + // Return the serialized bytes + Ok(buffer) +} + +async fn create_bundle( + con: &Mutex, + cache: &Mutex>>, + queries: &[String], + bundle_dir: &Path, +) -> Result<()> { + // Save cache to bundle_dir + // This is a placeholder and needs to be implemented based on your caching strategy + todo!("Implement saving cache to bundle directory"); + Ok(()) +} - fn query() -> Json { - let our_ids = vec![1, 3, 7, 13]; - warp::reply::json(&our_ids) +async fn load_bundle( + con: &Mutex, + cache: &Mutex>>, + bundle_dir: &Path, +) -> Result<()> { + // Load cache from bundle_dir + // This is a placeholder and needs to be implemented based on your caching strategy + todo!("Implement loading cache from bundle directory"); + Ok(()) +} + +async fn retrieve(cache: &Mutex>>, key: &str, f: F) -> Vec +where + F: FnOnce() -> Fut, + Fut: std::future::Future>>, +{ + let mut cache_lock = cache.lock().await; + if let Some(cached) = cache_lock.get(key) { + cached.clone() + } else { + let result = f().await.unwrap_or_else(|_| Vec::new()); + cache_lock.put(key.to_string(), result.clone()); + result } +} + +async fn handle_query( + State(state): State>, + params: QueryParams, +) -> Result { + let command = ¶ms.query_type; + let sql = params.sql.as_deref().unwrap_or(""); + + tracing::debug!("Command: '{}', SQL Query: '{}'", command, sql); + + match command.as_str() { + "exec" => { + execute(&state.con, sql) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Empty) + } + "arrow" => { + let buffer = retrieve(&state.cache, sql, || get_arrow_bytes(&state.con, sql)).await; + Ok(QueryResponse::Arrow(buffer)) + } + "json" => { + let json: Vec = retrieve(&state.cache, sql, || async { + get_json(&state.con, sql).await + }) + .await; + let string = String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Json(string)) + } + "create-bundle" => { + if let Some(queries) = params.queries { + create_bundle( + &state.con, + &state.cache, + &queries, + Path::new(".mosaic/bundle"), + ) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Empty) + } else { + Err(StatusCode::BAD_REQUEST) + } + } + "load-bundle" => { + load_bundle(&state.con, &state.cache, Path::new(".mosaic/bundle")) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Empty) + } + _ => Err(StatusCode::BAD_REQUEST), + } +} + +async fn handle_get( + State(state): State>, + Query(params): Query, +) -> Result { + handle_query(State(state), params).await +} + +async fn handle_post( + State(state): State>, + Json(params): Json, +) -> Result { + handle_query(State(state), params).await +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + tracing_subscriber::registry() + .with( + tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { + "duckdb_server_rust=debug,tower_http=debug,axum::rejection=trace".into() + }), + ) + .with(tracing_subscriber::fmt::layer()) + .init(); + + let con = Connection::open_in_memory()?; + let cache = lru::LruCache::new(100.try_into().unwrap()); + + let state = Arc::new(AppState { + con: Mutex::new(con), + cache: Mutex::new(cache), + }); + + let cors = CorsLayer::new() + .allow_origin(Any) + .allow_methods([Method::OPTIONS, Method::POST, Method::GET]) + .allow_headers(Any) + .max_age(Duration::from_secs(60) * 60 * 24); + + let app = Router::new() + .route("/", get(handle_get).post(handle_post)) + .with_state(state) + .layer(cors); + + let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 3000); - let server = warp::any() - .map(query) - .with(warp::reply::with::headers(headers)); + let mut listenfd = ListenFd::from_env(); + let listener = match listenfd.take_tcp_listener(0).unwrap() { + // if we are given a tcp listener on listen fd 0, we use that one + Some(listener) => { + listener.set_nonblocking(true).unwrap(); + TcpListener::from_std(listener).unwrap() + } + // otherwise fall back to local listening + None => TcpListener::bind(addr).await.unwrap(), + }; - println!("Listening on http://localhost:3030"); + // run it + tracing::debug!( + "DuckDB Server listening on http://{}", + listener.local_addr().unwrap() + ); + axum::serve(listener, app).await?; - warp::serve(server) - .run(([127, 0, 0, 1], 3030)) - .await; + Ok(()) } From 370f3a7e51c0dfe88feee5f1e38d32f20758e952 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 15:00:22 -0400 Subject: [PATCH 04/66] error handling --- packages/duckdb-server-rust/src/main.rs | 37 +++++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index e0aa9a51d..426105467 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -126,18 +126,22 @@ async fn load_bundle( Ok(()) } -async fn retrieve(cache: &Mutex>>, key: &str, f: F) -> Vec +async fn retrieve( + cache: &Mutex>>, + key: &str, + f: F +) -> Result> where F: FnOnce() -> Fut, Fut: std::future::Future>>, { let mut cache_lock = cache.lock().await; if let Some(cached) = cache_lock.get(key) { - cached.clone() + Ok(cached.clone()) } else { - let result = f().await.unwrap_or_else(|_| Vec::new()); + let result = f().await?; cache_lock.put(key.to_string(), result.clone()); - result + Ok(result) } } @@ -158,14 +162,23 @@ async fn handle_query( Ok(QueryResponse::Empty) } "arrow" => { - let buffer = retrieve(&state.cache, sql, || get_arrow_bytes(&state.con, sql)).await; + let buffer = retrieve(&state.cache, sql, || get_arrow_bytes(&state.con, sql)) + .await + .map_err(|e| { + tracing::error!("Arrow retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; Ok(QueryResponse::Arrow(buffer)) } "json" => { - let json: Vec = retrieve(&state.cache, sql, || async { + let json: Vec = retrieve(&state.cache, sql, || async { get_json(&state.con, sql).await }) - .await; + .await + .map_err(|e| { + tracing::error!("JSON retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; let string = String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(QueryResponse::Json(string)) } @@ -178,7 +191,10 @@ async fn handle_query( Path::new(".mosaic/bundle"), ) .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + .map_err(|e| { + tracing::error!("Bundle creation error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; Ok(QueryResponse::Empty) } else { Err(StatusCode::BAD_REQUEST) @@ -187,7 +203,10 @@ async fn handle_query( "load-bundle" => { load_bundle(&state.con, &state.cache, Path::new(".mosaic/bundle")) .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + .map_err(|e| { + tracing::error!("Bundle loading error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; Ok(QueryResponse::Empty) } _ => Err(StatusCode::BAD_REQUEST), From 1b59ea76afa79ef6570af6785708ec9b839b8847 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 15:17:19 -0400 Subject: [PATCH 05/66] abstract database --- packages/duckdb-server-rust/Cargo.lock | 1 + packages/duckdb-server-rust/Cargo.toml | 1 + packages/duckdb-server-rust/src/db.rs | 73 ++++++++++++++++++++ packages/duckdb-server-rust/src/main.rs | 90 +++++++------------------ 4 files changed, 98 insertions(+), 67 deletions(-) create mode 100644 packages/duckdb-server-rust/src/db.rs diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 7ada2aed8..0676a890c 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -721,6 +721,7 @@ version = "0.1.0" dependencies = [ "anyhow", "arrow", + "async-trait", "axum", "axum-server", "duckdb", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index d8c971cb0..805853658 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -19,3 +19,4 @@ arrow = "51.0" anyhow = "1.0" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } +async-trait = "0.1.80" diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs new file mode 100644 index 000000000..c77a28967 --- /dev/null +++ b/packages/duckdb-server-rust/src/db.rs @@ -0,0 +1,73 @@ +use async_trait::async_trait; +use anyhow::Result; +use duckdb::{arrow::array::RecordBatch, Connection}; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[async_trait] +pub trait Database: Send + Sync { + async fn execute(&self, sql: &str) -> Result<()>; + async fn get_json(&self, sql: &str) -> Result>; + async fn get_arrow_bytes(&self, sql: &str) -> Result>; +} + +pub struct DuckDbDatabase { + con: Arc>, +} + +impl DuckDbDatabase { + pub fn new(con: Connection) -> Self { + Self { + con: Arc::new(Mutex::new(con)), + } + } +} + +#[async_trait] +impl Database for DuckDbDatabase { + async fn execute(&self, sql: &str) -> Result<()> { + let conn = self.con.lock().await; + conn.execute_batch(sql)?; + Ok(()) + } + + async fn get_json(&self, sql: &str) -> Result> { + let conn = self.con.lock().await; + let mut stmt = conn.prepare(sql)?; + let arrow = stmt.query_arrow([])?; + + let rbs: Vec = arrow.collect(); + + let buf = Vec::new(); + let mut writer = arrow::json::ArrayWriter::new(buf); + for batch in rbs { + writer.write(&batch)?; + } + writer.finish()?; + let json_data = writer.into_inner(); + Ok(json_data) + } + + async fn get_arrow_bytes(&self, sql: &str) -> Result> { + let conn = self.con.lock().await; + let mut stmt = conn.prepare(sql)?; + let arrow = stmt.query_arrow([])?; + let schema = arrow.get_schema(); + + let rbs: Vec = arrow.collect(); + + let mut buffer: Vec = Vec::new(); + { + let schema_ref = schema.as_ref(); + let mut writer = arrow::ipc::writer::FileWriter::try_new(&mut buffer, schema_ref)?; + + for batch in rbs { + writer.write(&batch)?; + } + + writer.finish()?; + } + + Ok(buffer) + } +} \ No newline at end of file diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 426105467..be929dd27 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,5 +1,7 @@ +mod db; +use db::{Database, DuckDbDatabase}; + use anyhow::Result; -use arrow::{ipc::writer::FileWriter, json::ArrayWriter}; use axum::{ body::Bytes, extract::{Query, State}, @@ -9,7 +11,7 @@ use axum::{ routing::get, Router, }; -use duckdb::{arrow::array::RecordBatch, Connection}; +use duckdb::Connection; use listenfd::ListenFd; use serde::{Deserialize, Serialize}; use std::net::{Ipv4Addr, SocketAddr}; @@ -22,7 +24,7 @@ use tower_http::cors::{Any, CorsLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; struct AppState { - con: Mutex, + db: Arc, cache: Mutex>>, } @@ -55,56 +57,8 @@ impl IntoResponse for QueryResponse { } } -async fn execute(con: &Mutex, sql: &str) -> Result<()> { - let conn = con.lock().await; - conn.execute_batch(sql)?; - Ok(()) -} - -async fn get_json(con: &Mutex, sql: &str) -> Result> { - let conn = con.lock().await; - let mut stmt = conn.prepare(sql)?; - let arrow = stmt.query_arrow([])?; - - let rbs: Vec = arrow.collect(); - - let buf = Vec::new(); - let mut writer = ArrayWriter::new(buf); - for batch in rbs { - writer.write(&batch)?; - } - writer.finish()?; - let json_data = writer.into_inner(); - Ok(json_data) -} - -async fn get_arrow_bytes(con: &Mutex, sql: &str) -> Result> { - let conn = con.lock().await; - let mut stmt = conn.prepare(sql)?; - let arrow = stmt.query_arrow([])?; - let schema = arrow.get_schema(); - - let rbs: Vec = arrow.collect(); - - // Serialize RecordBatch to Arrow IPC format - let mut buffer: Vec = Vec::new(); - { - let schema_ref = schema.as_ref(); - let mut writer = FileWriter::try_new(&mut buffer, schema_ref)?; - - for batch in rbs { - writer.write(&batch)?; - } - - writer.finish()?; - } - - // Return the serialized bytes - Ok(buffer) -} - async fn create_bundle( - con: &Mutex, + db: &dyn Database, cache: &Mutex>>, queries: &[String], bundle_dir: &Path, @@ -116,7 +70,7 @@ async fn create_bundle( } async fn load_bundle( - con: &Mutex, + db: &dyn Database, cache: &Mutex>>, bundle_dir: &Path, ) -> Result<()> { @@ -129,7 +83,7 @@ async fn load_bundle( async fn retrieve( cache: &Mutex>>, key: &str, - f: F + f: F, ) -> Result> where F: FnOnce() -> Fut, @@ -156,13 +110,15 @@ async fn handle_query( match command.as_str() { "exec" => { - execute(&state.con, sql) + state + .db + .execute(sql) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(QueryResponse::Empty) } "arrow" => { - let buffer = retrieve(&state.cache, sql, || get_arrow_bytes(&state.con, sql)) + let buffer = retrieve(&state.cache, sql, || state.db.get_arrow_bytes(sql)) .await .map_err(|e| { tracing::error!("Arrow retrieval error: {:?}", e); @@ -171,21 +127,20 @@ async fn handle_query( Ok(QueryResponse::Arrow(buffer)) } "json" => { - let json: Vec = retrieve(&state.cache, sql, || async { - get_json(&state.con, sql).await - }) - .await - .map_err(|e| { - tracing::error!("JSON retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let json: Vec = + retrieve(&state.cache, sql, || async { state.db.get_json(sql).await }) + .await + .map_err(|e| { + tracing::error!("JSON retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; let string = String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(QueryResponse::Json(string)) } "create-bundle" => { if let Some(queries) = params.queries { create_bundle( - &state.con, + state.db.as_ref(), &state.cache, &queries, Path::new(".mosaic/bundle"), @@ -201,7 +156,7 @@ async fn handle_query( } } "load-bundle" => { - load_bundle(&state.con, &state.cache, Path::new(".mosaic/bundle")) + load_bundle(state.db.as_ref(), &state.cache, Path::new(".mosaic/bundle")) .await .map_err(|e| { tracing::error!("Bundle loading error: {:?}", e); @@ -239,10 +194,11 @@ async fn main() -> Result<(), Box> { .init(); let con = Connection::open_in_memory()?; + let db = Arc::new(DuckDbDatabase::new(con)); let cache = lru::LruCache::new(100.try_into().unwrap()); let state = Arc::new(AppState { - con: Mutex::new(con), + db, cache: Mutex::new(cache), }); From 49aec6758edfb930104da39cab85a02d18e324e5 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 18:13:06 -0400 Subject: [PATCH 06/66] make it work --- packages/duckdb-server-rust/Readme.md | 16 +++++++++++++--- packages/duckdb-server-rust/data | 1 + packages/duckdb-server-rust/src/main.rs | 5 +++-- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 120000 packages/duckdb-server-rust/data diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 381ef0e5d..bfcbd2e8f 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -1,18 +1,28 @@ # DuckDB Server -## Developers +## Build + +Build the release binary with + +```sh +cargo build --release +``` + +## Develop + +To run the server and restart it when the code changes, install `cargo-watch` and `systemfd` with ```sh cargo install cargo-watch systemfd ``` -Run with +Then run the server with ```sh systemfd --no-pid -s http::3000 -- cargo watch -x run ``` -Or just (but this won't restart when the code changes) +Or just use (but this won't restart when the code changes) ```sh cargo run diff --git a/packages/duckdb-server-rust/data b/packages/duckdb-server-rust/data new file mode 120000 index 000000000..e67b45590 --- /dev/null +++ b/packages/duckdb-server-rust/data @@ -0,0 +1 @@ +../../data \ No newline at end of file diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index be929dd27..595ef167a 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -91,6 +91,7 @@ where { let mut cache_lock = cache.lock().await; if let Some(cached) = cache_lock.get(key) { + tracing::debug!("Cache hit!"); Ok(cached.clone()) } else { let result = f().await?; @@ -106,7 +107,7 @@ async fn handle_query( let command = ¶ms.query_type; let sql = params.sql.as_deref().unwrap_or(""); - tracing::debug!("Command: '{}', SQL Query: '{}'", command, sql); + tracing::info!("Command: '{}', SQL Query: '{}'", command, sql); match command.as_str() { "exec" => { @@ -195,7 +196,7 @@ async fn main() -> Result<(), Box> { let con = Connection::open_in_memory()?; let db = Arc::new(DuckDbDatabase::new(con)); - let cache = lru::LruCache::new(100.try_into().unwrap()); + let cache = lru::LruCache::new(1000.try_into().unwrap()); let state = Arc::new(AppState { db, From d431610e98023c10368d2976f26f2a6ccc348f2e Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 18:55:35 -0400 Subject: [PATCH 07/66] http/2 --- .github/dependabot.yml | 8 ++++++ packages/duckdb-server-rust/.gitignore | 2 ++ packages/duckdb-server-rust/Cargo.lock | 38 ++++++++++++------------- packages/duckdb-server-rust/Readme.md | 8 +++++- packages/duckdb-server-rust/src/db.rs | 4 +-- packages/duckdb-server-rust/src/main.rs | 31 ++++++++++++++------ 6 files changed, 61 insertions(+), 30 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 05119d1e4..079d00709 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,3 +12,11 @@ updates: directory: "/packages/widget" schedule: interval: monthly + - package-ecosystem: pip + directory: "/packages/duckdb-server" + schedule: + interval: monthly + - package-ecosystem: cargo + directory: "/packages/duckdb-server-rust" + schedule: + interval: monthly diff --git a/packages/duckdb-server-rust/.gitignore b/packages/duckdb-server-rust/.gitignore index 2f7896d1d..2a02fa38b 100644 --- a/packages/duckdb-server-rust/.gitignore +++ b/packages/duckdb-server-rust/.gitignore @@ -1 +1,3 @@ target/ +localhost.pem +localhost-key.pem diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 0676a890c..0f04cfd06 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -317,7 +317,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -502,7 +502,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", "syn_derive", ] @@ -1465,7 +1465,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -1837,22 +1837,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -1985,7 +1985,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -1998,7 +1998,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2014,9 +2014,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" dependencies = [ "proc-macro2", "quote", @@ -2032,7 +2032,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2081,7 +2081,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2145,7 +2145,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2264,7 +2264,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2432,7 +2432,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", "wasm-bindgen-shared", ] @@ -2454,7 +2454,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2681,5 +2681,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index bfcbd2e8f..db533264e 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -19,7 +19,7 @@ cargo install cargo-watch systemfd Then run the server with ```sh -systemfd --no-pid -s http::3000 -- cargo watch -x run +systemfd --no-pid -s https::3000 -- cargo watch -x run ``` Or just use (but this won't restart when the code changes) @@ -27,3 +27,9 @@ Or just use (but this won't restart when the code changes) ```sh cargo run ``` + +Create certificates for HTTPS with + +```sh +mkcert localhost +``` diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index c77a28967..274c2d687 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,5 +1,5 @@ -use async_trait::async_trait; use anyhow::Result; +use async_trait::async_trait; use duckdb::{arrow::array::RecordBatch, Connection}; use std::sync::Arc; use tokio::sync::Mutex; @@ -70,4 +70,4 @@ impl Database for DuckDbDatabase { Ok(buffer) } -} \ No newline at end of file +} diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 595ef167a..09014ea41 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -11,14 +11,15 @@ use axum::{ routing::get, Router, }; +use axum_server::tls_rustls::RustlsConfig; use duckdb::Connection; use listenfd::ListenFd; use serde::{Deserialize, Serialize}; -use std::net::{Ipv4Addr, SocketAddr}; +use std::net::TcpListener; use std::path::Path; use std::sync::Arc; use std::time::Duration; -use tokio::net::TcpListener; +use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; use tokio::sync::Mutex; use tower_http::cors::{Any, CorsLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; @@ -185,6 +186,7 @@ async fn handle_post( #[tokio::main] async fn main() -> Result<(), Box> { + // Tracing setup tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { @@ -194,6 +196,7 @@ async fn main() -> Result<(), Box> { .with(tracing_subscriber::fmt::layer()) .init(); + // Database and state setup let con = Connection::open_in_memory()?; let db = Arc::new(DuckDbDatabase::new(con)); let cache = lru::LruCache::new(1000.try_into().unwrap()); @@ -203,36 +206,48 @@ async fn main() -> Result<(), Box> { cache: Mutex::new(cache), }); + // CORS setup let cors = CorsLayer::new() .allow_origin(Any) .allow_methods([Method::OPTIONS, Method::POST, Method::GET]) .allow_headers(Any) .max_age(Duration::from_secs(60) * 60 * 24); + // Router setup let app = Router::new() .route("/", get(handle_get).post(handle_post)) .with_state(state) .layer(cors); - let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 3000); + // TLS configuration + let config = RustlsConfig::from_pem_file( + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost.pem"), + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost-key.pem"), + ) + .await + .unwrap(); + // Listenfd setup + let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 3000); let mut listenfd = ListenFd::from_env(); let listener = match listenfd.take_tcp_listener(0).unwrap() { // if we are given a tcp listener on listen fd 0, we use that one Some(listener) => { listener.set_nonblocking(true).unwrap(); - TcpListener::from_std(listener).unwrap() + listener } // otherwise fall back to local listening - None => TcpListener::bind(addr).await.unwrap(), + None => TcpListener::bind(addr).unwrap(), }; - // run it + // Run the server tracing::debug!( - "DuckDB Server listening on http://{}", + "DuckDB Server listening on https://{}", listener.local_addr().unwrap() ); - axum::serve(listener, app).await?; + axum_server::from_tcp_rustls(listener, config) + .serve(app.into_make_service()) + .await?; Ok(()) } From 1348411a906b5ff145e48cbae5a01ed026beec4e Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 18:56:31 -0400 Subject: [PATCH 08/66] rust server script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 819261573..d67945536 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "lint": "lerna run lint", "test": "lerna run test", "server": "cd packages/duckdb-server && hatch run serve", + "server:rust": "cd packages/duckdb-server-rust && cargo run", "server:node": "nodemon packages/duckdb/bin/run-server.js", "dev": "vite", "release": "npm run test && npm run lint && lerna publish" From a9599547dcc413db02585737a1b2dba7ea8e660f Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 21:49:58 -0400 Subject: [PATCH 09/66] bundles --- packages/core/src/Coordinator.js | 19 ++- packages/core/src/DataCubeIndexer.js | 2 +- packages/core/src/FilterGroup.js | 2 +- packages/duckdb-server-rust/Cargo.lock | 13 ++ packages/duckdb-server-rust/Cargo.toml | 2 + packages/duckdb-server-rust/src/bundle.rs | 143 ++++++++++++++++++++++ packages/duckdb-server-rust/src/main.rs | 38 ++---- 7 files changed, 186 insertions(+), 33 deletions(-) create mode 100644 packages/duckdb-server-rust/src/bundle.rs diff --git a/packages/core/src/Coordinator.js b/packages/core/src/Coordinator.js index bef80c379..42d7471a3 100644 --- a/packages/core/src/Coordinator.js +++ b/packages/core/src/Coordinator.js @@ -9,7 +9,7 @@ let _instance; /** * Set or retrieve the coordinator instance. * - * @param {Coordinator} instance the coordinator instance to set + * @param {Coordinator} [instance] the coordinator instance to set * @returns {Coordinator} the coordinator instance */ export function coordinator(instance) { @@ -27,6 +27,7 @@ export class Coordinator { logger = console, manager = QueryManager() } = options; + /** @type {QueryManager} */ this.manager = manager; this.logger(logger); this.configure(options); @@ -87,11 +88,25 @@ export class Coordinator { return this.query(query, { ...options, cache: true, priority: Priority.Low }); } + /** + * Create a bundle of queries that can be loaded into the cache. + * + * @param {string} name The name of the bundle. + * @param {[string | {sql: string}, {alias: string}]} queries The queries to save into the bundle. + * @param {typeof Priority} priority Request priority. + * @returns + */ createBundle(name, queries, priority = Priority.Low) { - const options = { name, queries }; + const options = { name, queries: queries.map(q => typeof q == 'string' ? {sql: q} : q) }; return this.manager.request({ type: 'create-bundle', options }, priority); } + /** + * Load a bundle into the cache. + * @param {*} name The name of the bundle. + * @param {*} priority Request priority. + * @returns + */ loadBundle(name, priority = Priority.High) { const options = { name }; return this.manager.request({ type: 'load-bundle', options }, priority); diff --git a/packages/core/src/DataCubeIndexer.js b/packages/core/src/DataCubeIndexer.js index c5d67ef58..7f49be17d 100644 --- a/packages/core/src/DataCubeIndexer.js +++ b/packages/core/src/DataCubeIndexer.js @@ -19,7 +19,7 @@ export class DataCubeIndexer { * @param {*} options Options hash to configure the data cube indexes and pass selections to the coordinator. */ constructor(mc, { selection, temp = true }) { - /** @type import('./Coordinator.js').Coordinator */ + /** @type {import('./Coordinator.js').Coordinator} */ this.mc = mc; this.selection = selection; this.temp = temp; diff --git a/packages/core/src/FilterGroup.js b/packages/core/src/FilterGroup.js index 7d5189dfc..a931711fa 100644 --- a/packages/core/src/FilterGroup.js +++ b/packages/core/src/FilterGroup.js @@ -8,7 +8,7 @@ export class FilterGroup { * Falsy values disable indexing. */ constructor(coordinator, selection, index = true) { - /** @type import('./Coordinator.js').Coordinator */ + /** @type {import('./Coordinator.js').Coordinator} */ this.mc = coordinator; this.selection = selection; this.clients = new Set(); diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 0f04cfd06..3c6441430 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -727,8 +727,10 @@ dependencies = [ "duckdb", "listenfd", "lru", + "regex", "serde", "serde_json", + "sha2", "tokio", "tower-http", "tracing", @@ -1899,6 +1901,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 805853658..45e041bc8 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -20,3 +20,5 @@ anyhow = "1.0" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } async-trait = "0.1.80" +regex = "1.5" +sha2 = "0.10" diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs new file mode 100644 index 000000000..495e7804d --- /dev/null +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -0,0 +1,143 @@ +use crate::db::Database; +use anyhow::{Context, Result}; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::Path; +use tokio::sync::Mutex; + +#[derive(Serialize, Deserialize)] +pub struct Manifest { + tables: Vec, + queries: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct Query { + sql: String, + alias: Option, +} + +fn get_key(sql: &str, command: &str) -> String { + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(sql); + hasher.update(command); + format!("{:x}.{}", hasher.finalize(), command) +} + +pub async fn create_bundle( + db: &dyn Database, + cache: &Mutex>>, + queries: Vec, + bundle_dir: &Path, +) -> Result { + let describe_re = Regex::new(r"^DESCRIBE ")?; + let pragma_re = Regex::new(r"^PRAGMA ")?; + let view_re = Regex::new(r"^CREATE( TEMP| TEMPORARY)? VIEW")?; + let table_re = Regex::new(r"^CREATE( TEMP| TEMPORARY)? TABLE( IF NOT EXISTS)? ([^\s]+)")?; + + let mut manifest = Manifest { + tables: Vec::new(), + queries: Vec::new(), + }; + + fs::create_dir_all(bundle_dir).context("Failed to create bundle directory")?; + + for query in queries { + let sql = &query.sql; + + if let Some(alias) = &query.alias { + let file = bundle_dir.join(format!("{}.parquet", alias)); + db.execute(&format!( + "COPY ({}) TO '{}' (FORMAT PARQUET)", + sql, + file.display() + )) + .await?; + manifest.tables.push(alias.clone()); + } else if sql.starts_with("CREATE ") { + if view_re.is_match(sql) { + continue; // Ignore views + } + + if let Some(captures) = table_re.captures(sql) { + let table = captures.get(3).unwrap().as_str(); + let file = bundle_dir.join(format!("{}.parquet", table)); + db.execute(sql).await?; + db.execute(&format!( + "COPY {} TO '{}' (FORMAT PARQUET)", + table, + file.display() + )) + .await?; + manifest.tables.push(table.to_string()); + } + } else if !pragma_re.is_match(sql) { + let command = if describe_re.is_match(sql) { + "json" + } else { + "arrow" + }; + let key = get_key(sql, command); + let result = if command == "arrow" { + db.get_arrow_bytes(sql).await? + } else { + db.get_json(sql).await? + }; + + fs::write(bundle_dir.join(&key), &result) + .context("Failed to write query result to file")?; + manifest.queries.push(key); + } + } + + let manifest_file = bundle_dir.join("bundle.json"); + let manifest_json = + serde_json::to_string_pretty(&manifest).context("Failed to serialize manifest")?; + fs::write(manifest_file, manifest_json).context("Failed to write manifest to file")?; + + Ok(manifest) +} + +pub async fn load_bundle( + db: &dyn Database, + cache: &Mutex>>, + bundle_dir: &Path, +) -> Result<()> { + let manifest_file = bundle_dir.join("bundle.json"); + let manifest_json = + fs::read_to_string(manifest_file).context("Failed to read manifest file")?; + let manifest: Manifest = + serde_json::from_str(&manifest_json).context("Failed to deserialize manifest")?; + + // Load precomputed query results into the cache + let mut cache_lock = cache.lock().await; + for key in &manifest.queries { + let file = bundle_dir.join(key); + let is_json = file.extension().and_then(|ext| ext.to_str()) == Some("json"); + let data = fs::read(&file).context("Failed to read query result file")?; + if is_json { + let json_str = String::from_utf8(data).context("Failed to parse JSON data as UTF-8")?; + let json_value: serde_json::Value = + serde_json::from_str(&json_str).context("Failed to parse JSON data")?; + cache_lock.put(key.clone(), serde_json::to_vec(&json_value)?); + } else { + cache_lock.put(key.clone(), data); + } + } + drop(cache_lock); + + // Load precomputed temp tables into the database + for table in &manifest.tables { + let file = bundle_dir.join(format!("{}.parquet", table)); + db.execute(&format!( + "CREATE TEMP TABLE IF NOT EXISTS {} AS SELECT * FROM '{}'", + table, + file.display() + )) + .await?; + } + + Ok(()) +} diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 09014ea41..b453c0bde 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,6 +1,3 @@ -mod db; -use db::{Database, DuckDbDatabase}; - use anyhow::Result; use axum::{ body::Bytes, @@ -24,6 +21,12 @@ use tokio::sync::Mutex; use tower_http::cors::{Any, CorsLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +mod bundle; +mod db; + +use bundle::{create_bundle, load_bundle, Query as BundleQuery}; +use db::{Database, DuckDbDatabase}; + struct AppState { db: Arc, cache: Mutex>>, @@ -34,7 +37,7 @@ struct QueryParams { #[serde(rename = "type")] query_type: String, sql: Option, - queries: Option>, + queries: Option>, } enum QueryResponse { @@ -58,29 +61,6 @@ impl IntoResponse for QueryResponse { } } -async fn create_bundle( - db: &dyn Database, - cache: &Mutex>>, - queries: &[String], - bundle_dir: &Path, -) -> Result<()> { - // Save cache to bundle_dir - // This is a placeholder and needs to be implemented based on your caching strategy - todo!("Implement saving cache to bundle directory"); - Ok(()) -} - -async fn load_bundle( - db: &dyn Database, - cache: &Mutex>>, - bundle_dir: &Path, -) -> Result<()> { - // Load cache from bundle_dir - // This is a placeholder and needs to be implemented based on your caching strategy - todo!("Implement loading cache from bundle directory"); - Ok(()) -} - async fn retrieve( cache: &Mutex>>, key: &str, @@ -130,7 +110,7 @@ async fn handle_query( } "json" => { let json: Vec = - retrieve(&state.cache, sql, || async { state.db.get_json(sql).await }) + retrieve(&state.cache, sql, || state.db.get_json(sql)) .await .map_err(|e| { tracing::error!("JSON retrieval error: {:?}", e); @@ -144,7 +124,7 @@ async fn handle_query( create_bundle( state.db.as_ref(), &state.cache, - &queries, + queries, Path::new(".mosaic/bundle"), ) .await From da983a20f6ae6960df6821ad0c506485674e53f9 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 6 Jul 2024 22:03:50 -0400 Subject: [PATCH 10/66] option for https --- dev/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/index.html b/dev/index.html index 8e52c152b..0eb4d3fe5 100644 --- a/dev/index.html +++ b/dev/index.html @@ -65,6 +65,7 @@ + @@ -142,7 +143,9 @@ setConnector(); async function setConnector() { - await setDatabaseConnector(connectorMenu.value); + const value = connectorMenu.value; + const isHttps = value === 'rest_https'; + await setDatabaseConnector(isHttps ? 'rest' : value, isHttps ? 'https://localhost:3000/' : undefined); reload(); } From 884f139b43ddec78c51b9e478f5b26d6fdf59340 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 12:02:10 -0400 Subject: [PATCH 11/66] support bundle handlings in connnectors --- packages/core/src/connectors/rest.js | 6 +++--- packages/core/src/connectors/socket.js | 2 +- packages/core/src/connectors/wasm.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/connectors/rest.js b/packages/core/src/connectors/rest.js index 00c788698..388b0889d 100644 --- a/packages/core/src/connectors/rest.js +++ b/packages/core/src/connectors/rest.js @@ -5,7 +5,7 @@ export function restConnector(uri = 'http://localhost:3000/') { /** * Query the DuckDB server. * @param {object} query - * @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'. + * @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type. * @param {string} query.sql A SQL query string. * @returns the query result */ @@ -19,9 +19,9 @@ export function restConnector(uri = 'http://localhost:3000/') { body: JSON.stringify(query) }); - return query.type === 'exec' ? req + return query.type === 'json' ? (await req).json() : query.type === 'arrow' ? tableFromIPC(req) - : (await req).json(); + : req; } }; } diff --git a/packages/core/src/connectors/socket.js b/packages/core/src/connectors/socket.js index 95f070545..1e4af0fd5 100644 --- a/packages/core/src/connectors/socket.js +++ b/packages/core/src/connectors/socket.js @@ -84,7 +84,7 @@ export function socketConnector(uri = 'ws://localhost:3000/') { /** * Query the DuckDB server. * @param {object} query - * @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'. + * @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type. * @param {string} query.sql A SQL query string. * @returns the query result */ diff --git a/packages/core/src/connectors/wasm.js b/packages/core/src/connectors/wasm.js index 3f20640ca..eafee4091 100644 --- a/packages/core/src/connectors/wasm.js +++ b/packages/core/src/connectors/wasm.js @@ -45,7 +45,7 @@ export function wasmConnector(options = {}) { /** * Query the DuckDB-WASM instance. * @param {object} query - * @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'. + * @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type. * @param {string} query.sql A SQL query string. * @returns the query result */ @@ -53,9 +53,9 @@ export function wasmConnector(options = {}) { const { type, sql } = query; const con = await getConnection(); const result = await con.query(sql); - return type === 'exec' ? undefined + return type === 'json' ? result.toArray() : type === 'arrow' ? result - : result.toArray(); + : undefined; } }; } From af2d6753bdaff5fb8bcaf07676b7a9c61ea3efeb Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 12:02:22 -0400 Subject: [PATCH 12/66] simplify server --- packages/duckdb/src/data-server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/duckdb/src/data-server.js b/packages/duckdb/src/data-server.js index 2f2e81ac2..184c24002 100644 --- a/packages/duckdb/src/data-server.js +++ b/packages/duckdb/src/data-server.js @@ -103,7 +103,7 @@ export function queryHandler(db, queryCache) { try { const { sql, type = 'json' } = query; - console.log(`> ${type.toUpperCase()}${sql ? ' ' + sql : ''}`); + console.log(`> ${type.toUpperCase()}${sql ? ` ${sql}` : ''}`); // process query and return result switch (type) { From ed4bec9396b259b89f8575bec16f0c4277621391 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 12:02:35 -0400 Subject: [PATCH 13/66] priority queue as class --- packages/core/src/QueryManager.js | 4 +- packages/core/src/util/priority-queue.js | 151 +++++++++++------------ 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/packages/core/src/QueryManager.js b/packages/core/src/QueryManager.js index 1189a7b34..ef28b3517 100644 --- a/packages/core/src/QueryManager.js +++ b/packages/core/src/QueryManager.js @@ -1,13 +1,13 @@ import { consolidator } from './QueryConsolidator.js'; import { lruCache, voidCache } from './util/cache.js'; -import { priorityQueue } from './util/priority-queue.js'; +import { PriorityQueue } from './util/priority-queue.js'; import { QueryResult } from './util/query-result.js'; export const Priority = { High: 0, Normal: 1, Low: 2 }; export class QueryManager { constructor() { - this.queue = priorityQueue(3); + this.queue = new PriorityQueue(3); this.db = null; this.clientCache = null; this._logger = null; diff --git a/packages/core/src/util/priority-queue.js b/packages/core/src/util/priority-queue.js index 4346fe063..d92925ade 100644 --- a/packages/core/src/util/priority-queue.js +++ b/packages/core/src/util/priority-queue.js @@ -1,85 +1,84 @@ -/** - * Create a new priority queue instance. - * @param {number} ranks An integer number of rank-order priority levels. - * @returns A priority queue instance. - */ -export function priorityQueue(ranks) { - // one list for each integer priority level - const queue = Array.from( +export class PriorityQueue { + /** + * Create a new priority queue instance. + * @param {number} ranks An integer number of rank-order priority levels. + */ + constructor(ranks) { + // one list for each integer priority level + this.queue = Array.from( { length: ranks }, () => ({ head: null, tail: null }) ); + } - return { - /** - * Indicate if the queue is empty. - * @returns [boolean] true if empty, false otherwise. - */ - isEmpty() { - return queue.every(list => !list.head); - }, + /** + * Indicate if the queue is empty. + * @returns {boolean} true if empty, false otherwise. + */ + isEmpty() { + return this.queue.every((list) => !list.head); + } - /** - * Insert an item into the queue with a given priority rank. - * @param {*} item The item to add. - * @param {number} rank The integer priority rank. - * Priority ranks are integers starting at zero. - * Lower ranks indicate higher priority. - */ - insert(item, rank) { - const list = queue[rank]; - if (!list) { - throw new Error(`Invalid queue priority rank: ${rank}`); - } + /** + * Insert an item into the queue with a given priority rank. + * @param {*} item The item to add. + * @param {number} rank The integer priority rank. + * Priority ranks are integers starting at zero. + * Lower ranks indicate higher priority. + */ + insert(item, rank) { + const list = this.queue[rank]; + if (!list) { + throw new Error(`Invalid queue priority rank: ${rank}`); + } - const node = { item, next: null }; - if (list.head === null) { - list.head = list.tail = node; - } else { - list.tail = (list.tail.next = node); - } - }, + const node = { item, next: null }; + if (list.head === null) { + list.head = list.tail = node; + } else { + list.tail = list.tail.next = node; + } + } - /** - * Remove a set of items from the queue, regardless of priority rank. - * If a provided item is not in the queue it will be ignored. - * @param {(item: *) => boolean} test A predicate function to test - * if an item should be removed (true to drop, false to keep). - */ - remove(test) { - for (const list of queue) { - let { head, tail } = list; - for (let prev = null, curr = head; curr; prev = curr, curr = curr.next) { - if (test(curr.item)) { - if (curr === head) { - head = curr.next; - } else { - prev.next = curr.next; - } - if (curr === tail) tail = prev || head; - } - } - list.head = head; - list.tail = tail; - } - }, + /** + * Remove a set of items from the queue, regardless of priority rank. + * If a provided item is not in the queue it will be ignored. + * @param {(item: *) => boolean} test A predicate function to test + * if an item should be removed (true to drop, false to keep). + */ + remove(test) { + for (const list of this.queue) { + let { head, tail } = list; + for (let prev = null, curr = head; curr; prev = curr, curr = curr.next) { + if (test(curr.item)) { + if (curr === head) { + head = curr.next; + } else { + prev.next = curr.next; + } + if (curr === tail) tail = prev || head; + } + } + list.head = head; + list.tail = tail; + } + } - /** - * Remove and return the next highest priority item. - * @returns {*} The next item in the queue, - * or undefined if this queue is empty. - */ - next() { - for (const list of queue) { - const { head } = list; - if (head !== null) { - list.head = head.next; - if (list.tail === head) { - list.tail = null; - } - return head.item; - } - } - } - }; + /** + * Remove and return the next highest priority item. + * @returns {*} The next item in the queue, + * or undefined if this queue is empty. + */ + next() { + for (const list of this.queue) { + const { head } = list; + if (head !== null) { + list.head = head.next; + if (list.tail === head) { + list.tail = null; + } + return head.item; + } + } + } } From db1c70c0884be3c0006276fc0851ee49b2c2e8e6 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 12:02:51 -0400 Subject: [PATCH 14/66] add bundle name to python --- packages/duckdb-server/pkg/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/duckdb-server/pkg/server.py b/packages/duckdb-server/pkg/server.py index 92c3757f4..f0339615e 100644 --- a/packages/duckdb-server/pkg/server.py +++ b/packages/duckdb-server/pkg/server.py @@ -94,10 +94,10 @@ def handle_query(handler: Handler, con, cache, query): json = retrieve(cache, query, partial(get_json, con)) handler.json(json) elif command == "create-bundle": - create_bundle(con, cache, query.get("queries"), BUNDLE_DIR) + create_bundle(con, cache, query.get("queries"), BUNDLE_DIR / query.get("name")) handler.done() elif command == "load-bundle": - load_bundle(con, cache, BUNDLE_DIR) + load_bundle(con, cache, BUNDLE_DIR / query.get("name")) handler.done() else: raise ValueError(f"Unknown command {command}") From 463930b586d93f0e54a3622e8eca35ad2a0f9430 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 12:03:21 -0400 Subject: [PATCH 15/66] bundle handling --- dev/bundle.html | 22 +++-- dev/index.html | 4 +- dev/setup.js | 11 ++- .../duckdb-server-rust/.vscode/launch.json | 45 +++++++++ packages/duckdb-server-rust/src/bundle.rs | 2 +- packages/duckdb-server-rust/src/main.rs | 91 +++++++++++-------- 6 files changed, 119 insertions(+), 56 deletions(-) create mode 100644 packages/duckdb-server-rust/.vscode/launch.json diff --git a/dev/bundle.html b/dev/bundle.html index 1bd8dd35f..ee947c43a 100644 --- a/dev/bundle.html +++ b/dev/bundle.html @@ -17,6 +17,7 @@ @@ -47,28 +48,31 @@ async function create() { try { - await coordinator().createBundle('test', queries); - output.innerText = "Created bundle" + await coordinator.createBundle('test', queries); + output.innerText = "Created bundle"; } catch(err) { - output.innerText = `Error: ${err}` + output.innerText = `Error: ${err}`; + console.log(err.stack); } } async function load() { try { - await coordinator().loadBundle('test'); - output.innerText = "Loaded bundle" + await coordinator.loadBundle('test'); + output.innerText = "Loaded bundle"; } catch(err) { - output.innerText = `Error: ${err}` + output.innerText = `Error: ${err}`; + console.log(err.stack); } } async function query() { try { - const result = await coordinator().query(queries[1], {cache: false}); - output.innerText = `Result = ${result}` + const result = await coordinator.query(queries[1], {cache: false}); + output.innerText = `Result = ${result}`; } catch(err) { - output.innerText = `Error: ${err}` + output.innerText = `Error: ${err}`; + console.log(err.stack); } } diff --git a/dev/index.html b/dev/index.html index 0eb4d3fe5..f9ba18789 100644 --- a/dev/index.html +++ b/dev/index.html @@ -143,9 +143,7 @@ setConnector(); async function setConnector() { - const value = connectorMenu.value; - const isHttps = value === 'rest_https'; - await setDatabaseConnector(isHttps ? 'rest' : value, isHttps ? 'https://localhost:3000/' : undefined); + await setDatabaseConnector(connectorMenu.value); reload(); } diff --git a/dev/setup.js b/dev/setup.js index 863821600..86cfc5702 100644 --- a/dev/setup.js +++ b/dev/setup.js @@ -16,17 +16,20 @@ export function clear() { let wasm; -export async function setDatabaseConnector(type, options) { +export async function setDatabaseConnector(type) { let connector; switch (type) { case 'socket': - connector = socketConnector(options); + connector = socketConnector(); break; case 'rest': - connector = restConnector(options); + connector = restConnector(); + break; + case 'rest_https': + connector = restConnector('https://localhost:3000/'); break; case 'wasm': - connector = wasm || (wasm = wasmConnector(options)); + connector = wasm || (wasm = wasmConnector()); break; default: throw new Error(`Unrecognized connector type: ${type}`); diff --git a/packages/duckdb-server-rust/.vscode/launch.json b/packages/duckdb-server-rust/.vscode/launch.json new file mode 100644 index 000000000..a501cc629 --- /dev/null +++ b/packages/duckdb-server-rust/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'duckdb-server-rust'", + "cargo": { + "args": [ + "build", + "--bin=duckdb-server-rust", + "--package=duckdb-server-rust" + ], + "filter": { + "name": "duckdb-server-rust", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'duckdb-server-rust'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=duckdb-server-rust", + "--package=duckdb-server-rust" + ], + "filter": { + "name": "duckdb-server-rust", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 495e7804d..57f1078d2 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -12,7 +12,7 @@ pub struct Manifest { queries: Vec, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub struct Query { sql: String, alias: Option, diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index b453c0bde..2941f2237 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -32,11 +32,12 @@ struct AppState { cache: Mutex>>, } -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, Serialize, Debug)] struct QueryParams { #[serde(rename = "type")] query_type: String, sql: Option, + name: Option, queries: Option>, } @@ -86,65 +87,77 @@ async fn handle_query( params: QueryParams, ) -> Result { let command = ¶ms.query_type; - let sql = params.sql.as_deref().unwrap_or(""); - - tracing::info!("Command: '{}', SQL Query: '{}'", command, sql); + tracing::info!("Command: '{}', Params: '{:?}'", command, params); match command.as_str() { "exec" => { - state - .db - .execute(sql) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - Ok(QueryResponse::Empty) + if let Some(sql) = params.sql.as_deref() { + state + .db + .execute(sql) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Empty) + } else { + Err(StatusCode::BAD_REQUEST) + } } "arrow" => { - let buffer = retrieve(&state.cache, sql, || state.db.get_arrow_bytes(sql)) - .await - .map_err(|e| { - tracing::error!("Arrow retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(QueryResponse::Arrow(buffer)) + if let Some(sql) = params.sql.as_deref() { + let buffer = retrieve(&state.cache, sql, || state.db.get_arrow_bytes(sql)) + .await + .map_err(|e| { + tracing::error!("Arrow retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; + Ok(QueryResponse::Arrow(buffer)) + } else { + Err(StatusCode::BAD_REQUEST) + } } "json" => { - let json: Vec = - retrieve(&state.cache, sql, || state.db.get_json(sql)) + if let Some(sql) = params.sql.as_deref() { + let json: Vec = retrieve(&state.cache, sql, || state.db.get_json(sql)) .await .map_err(|e| { tracing::error!("JSON retrieval error: {:?}", e); StatusCode::INTERNAL_SERVER_ERROR })?; - let string = String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - Ok(QueryResponse::Json(string)) + let string = + String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok(QueryResponse::Json(string)) + } else { + Err(StatusCode::BAD_REQUEST) + } } "create-bundle" => { if let Some(queries) = params.queries { - create_bundle( - state.db.as_ref(), - &state.cache, - queries, - Path::new(".mosaic/bundle"), - ) - .await - .map_err(|e| { - tracing::error!("Bundle creation error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + create_bundle(state.db.as_ref(), &state.cache, queries, &bundle_path) + .await + .map_err(|e| { + tracing::error!("Bundle creation error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; Ok(QueryResponse::Empty) } else { Err(StatusCode::BAD_REQUEST) } } "load-bundle" => { - load_bundle(state.db.as_ref(), &state.cache, Path::new(".mosaic/bundle")) - .await - .map_err(|e| { - tracing::error!("Bundle loading error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(QueryResponse::Empty) + if let Some(bundle_name) = params.name { + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + load_bundle(state.db.as_ref(), &state.cache, &bundle_path) + .await + .map_err(|e| { + tracing::error!("Bundle loading error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; + Ok(QueryResponse::Empty) + } else { + Err(StatusCode::BAD_REQUEST) + } } _ => Err(StatusCode::BAD_REQUEST), } From b1e7cc98bf52486c735b7476a516c565d869d029 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 13:58:32 -0400 Subject: [PATCH 16/66] fix --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 079d00709..e4566547c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,7 +12,7 @@ updates: directory: "/packages/widget" schedule: interval: monthly - - package-ecosystem: pip + - package-ecosystem: pip directory: "/packages/duckdb-server" schedule: interval: monthly From e73d430341f827af990bab177a71d173abf6ba55 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 14:56:15 -0400 Subject: [PATCH 17/66] update deps --- packages/duckdb-server-rust/Cargo.lock | 19 +++++-------------- packages/duckdb-server-rust/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 3c6441430..4b9926169 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -554,9 +554,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437" dependencies = [ "jobserver", "libc", @@ -925,15 +925,6 @@ dependencies = [ "ahash 0.7.8", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash 0.8.11", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -1252,11 +1243,11 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.10.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.14.5", ] [[package]] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 45e041bc8..249e3f517 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -14,7 +14,7 @@ tower-http = { version = "0.5.0", features = ["cors"] } listenfd = "1.0.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -lru = "0.10" +lru = "0.12" arrow = "51.0" anyhow = "1.0" tracing = "0.1" From 5ba673ba121b0a0aa26afb3143183885b2a5fbaa Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 15:34:32 -0400 Subject: [PATCH 18/66] don't collect vectors, return real json --- packages/duckdb-server-rust/src/db.rs | 8 ++------ packages/duckdb-server-rust/src/main.rs | 7 ++++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index 274c2d687..ee04d2d51 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -36,11 +36,9 @@ impl Database for DuckDbDatabase { let mut stmt = conn.prepare(sql)?; let arrow = stmt.query_arrow([])?; - let rbs: Vec = arrow.collect(); - let buf = Vec::new(); let mut writer = arrow::json::ArrayWriter::new(buf); - for batch in rbs { + for batch in arrow { writer.write(&batch)?; } writer.finish()?; @@ -54,14 +52,12 @@ impl Database for DuckDbDatabase { let arrow = stmt.query_arrow([])?; let schema = arrow.get_schema(); - let rbs: Vec = arrow.collect(); - let mut buffer: Vec = Vec::new(); { let schema_ref = schema.as_ref(); let mut writer = arrow::ipc::writer::FileWriter::try_new(&mut buffer, schema_ref)?; - for batch in rbs { + for batch in arrow { writer.write(&batch)?; } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 2941f2237..5b2e99f87 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -50,7 +50,12 @@ enum QueryResponse { impl IntoResponse for QueryResponse { fn into_response(self) -> Response { match self { - QueryResponse::Json(value) => value.into_response(), + QueryResponse::Json(value) => ( + StatusCode::OK, + [("Content-Type", "application/json")], + value, + ) + .into_response(), QueryResponse::Arrow(bytes) => ( StatusCode::OK, [("Content-Type", "application/octet-stream")], From 6f5a05a75ae33998648bdd2693a0772d98ab86ef Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 15:47:13 -0400 Subject: [PATCH 19/66] fix bundle and caching --- packages/duckdb-server-rust/src/bundle.rs | 12 +++------ packages/duckdb-server-rust/src/cache.rs | 32 +++++++++++++++++++++++ packages/duckdb-server-rust/src/main.rs | 26 +++--------------- 3 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 packages/duckdb-server-rust/src/cache.rs diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 57f1078d2..44408bfd2 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -1,4 +1,5 @@ use crate::db::Database; +use crate::cache::get_key; use anyhow::{Context, Result}; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -18,14 +19,6 @@ pub struct Query { alias: Option, } -fn get_key(sql: &str, command: &str) -> String { - use sha2::{Digest, Sha256}; - let mut hasher = Sha256::new(); - hasher.update(sql); - hasher.update(command); - format!("{:x}.{}", hasher.finalize(), command) -} - pub async fn create_bundle( db: &dyn Database, cache: &Mutex>>, @@ -107,13 +100,14 @@ pub async fn load_bundle( ) -> Result<()> { let manifest_file = bundle_dir.join("bundle.json"); let manifest_json = - fs::read_to_string(manifest_file).context("Failed to read manifest file")?; + fs::read_to_string(&manifest_file).context("Failed to read manifest file")?; let manifest: Manifest = serde_json::from_str(&manifest_json).context("Failed to deserialize manifest")?; // Load precomputed query results into the cache let mut cache_lock = cache.lock().await; for key in &manifest.queries { + tracing::debug!("Key {}", key); let file = bundle_dir.join(key); let is_json = file.extension().and_then(|ext| ext.to_str()) == Some("json"); let data = fs::read(&file).context("Failed to read query result file")?; diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs new file mode 100644 index 000000000..ff917dadc --- /dev/null +++ b/packages/duckdb-server-rust/src/cache.rs @@ -0,0 +1,32 @@ +use tokio::sync::Mutex; +use anyhow::Result; + +pub fn get_key(sql: &str, command: &str) -> String { + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(sql); + hasher.update(command); + format!("{:x}.{}", hasher.finalize(), command) +} + +pub async fn retrieve( + cache: &Mutex>>, + sql: &str, + command: &str, + f: F, +) -> Result> +where + F: FnOnce() -> Fut, + Fut: std::future::Future>>, +{ + let key = get_key(sql, command); + let mut cache_lock = cache.lock().await; + if let Some(cached) = cache_lock.get(&key) { + tracing::debug!("Cache hit {}!", key); + Ok(cached.clone()) + } else { + let result = f().await?; + cache_lock.put(key, result.clone()); + Ok(result) + } +} diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 5b2e99f87..03695448b 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -22,9 +22,11 @@ use tower_http::cors::{Any, CorsLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod bundle; +mod cache; mod db; use bundle::{create_bundle, load_bundle, Query as BundleQuery}; +use cache::retrieve; use db::{Database, DuckDbDatabase}; struct AppState { @@ -67,26 +69,6 @@ impl IntoResponse for QueryResponse { } } -async fn retrieve( - cache: &Mutex>>, - key: &str, - f: F, -) -> Result> -where - F: FnOnce() -> Fut, - Fut: std::future::Future>>, -{ - let mut cache_lock = cache.lock().await; - if let Some(cached) = cache_lock.get(key) { - tracing::debug!("Cache hit!"); - Ok(cached.clone()) - } else { - let result = f().await?; - cache_lock.put(key.to_string(), result.clone()); - Ok(result) - } -} - async fn handle_query( State(state): State>, params: QueryParams, @@ -109,7 +91,7 @@ async fn handle_query( } "arrow" => { if let Some(sql) = params.sql.as_deref() { - let buffer = retrieve(&state.cache, sql, || state.db.get_arrow_bytes(sql)) + let buffer = retrieve(&state.cache, sql, command, || state.db.get_arrow_bytes(sql)) .await .map_err(|e| { tracing::error!("Arrow retrieval error: {:?}", e); @@ -122,7 +104,7 @@ async fn handle_query( } "json" => { if let Some(sql) = params.sql.as_deref() { - let json: Vec = retrieve(&state.cache, sql, || state.db.get_json(sql)) + let json: Vec = retrieve(&state.cache, sql, command, || state.db.get_json(sql)) .await .map_err(|e| { tracing::error!("JSON retrieval error: {:?}", e); From c7b5591906fba2d0c53fa60b9ebe9f9525712cbe Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 15:59:12 -0400 Subject: [PATCH 20/66] implement persists --- packages/duckdb-server-rust/src/cache.rs | 8 +++++++- packages/duckdb-server-rust/src/main.rs | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index ff917dadc..e260ff2ca 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -13,6 +13,7 @@ pub async fn retrieve( cache: &Mutex>>, sql: &str, command: &str, + persist: bool, f: F, ) -> Result> where @@ -24,9 +25,14 @@ where if let Some(cached) = cache_lock.get(&key) { tracing::debug!("Cache hit {}!", key); Ok(cached.clone()) - } else { + } else if persist { let result = f().await?; cache_lock.put(key, result.clone()); Ok(result) + } else { + // no need to keep the cache lock if we are not storing anything + drop(cache_lock); + let result = f().await?; + Ok(result) } } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 03695448b..a460cc505 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -38,6 +38,7 @@ struct AppState { struct QueryParams { #[serde(rename = "type")] query_type: String, + persist: Option, sql: Option, name: Option, queries: Option>, @@ -91,7 +92,8 @@ async fn handle_query( } "arrow" => { if let Some(sql) = params.sql.as_deref() { - let buffer = retrieve(&state.cache, sql, command, || state.db.get_arrow_bytes(sql)) + let persist = params.persist.unwrap_or(true); + let buffer = retrieve(&state.cache, sql, command, persist, || state.db.get_arrow_bytes(sql)) .await .map_err(|e| { tracing::error!("Arrow retrieval error: {:?}", e); @@ -104,7 +106,8 @@ async fn handle_query( } "json" => { if let Some(sql) = params.sql.as_deref() { - let json: Vec = retrieve(&state.cache, sql, command, || state.db.get_json(sql)) + let persist = params.persist.unwrap_or(true); + let json: Vec = retrieve(&state.cache, sql, command, persist, || state.db.get_json(sql)) .await .map_err(|e| { tracing::error!("JSON retrieval error: {:?}", e); From 996a0962b3eaf469ffbb883cffe352268364a794 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 16:38:03 -0400 Subject: [PATCH 21/66] cache in bundle creating, simplify bundle loading --- packages/duckdb-server-rust/src/bundle.rs | 27 ++++++++-------------- packages/duckdb-server-rust/src/cache.rs | 25 ++++++++++---------- packages/duckdb-server-rust/src/db.rs | 2 +- packages/duckdb-server-rust/src/main.rs | 28 +++++++++++++---------- 4 files changed, 39 insertions(+), 43 deletions(-) diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 44408bfd2..4731a8121 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -1,5 +1,5 @@ +use crate::cache::{get_key, retrieve}; use crate::db::Database; -use crate::cache::get_key; use anyhow::{Context, Result}; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -73,12 +73,13 @@ pub async fn create_bundle( "arrow" }; let key = get_key(sql, command); - let result = if command == "arrow" { - db.get_arrow_bytes(sql).await? - } else { - db.get_json(sql).await? - }; - + let result = retrieve(cache, sql, command, true, || { + if command == "arrow" { + db.get_arrow_bytes(sql) + } else { + db.get_json(sql) + } + }).await?; fs::write(bundle_dir.join(&key), &result) .context("Failed to write query result to file")?; manifest.queries.push(key); @@ -107,18 +108,10 @@ pub async fn load_bundle( // Load precomputed query results into the cache let mut cache_lock = cache.lock().await; for key in &manifest.queries { - tracing::debug!("Key {}", key); + tracing::debug!("Load from bundle into cache: {}", key); let file = bundle_dir.join(key); - let is_json = file.extension().and_then(|ext| ext.to_str()) == Some("json"); let data = fs::read(&file).context("Failed to read query result file")?; - if is_json { - let json_str = String::from_utf8(data).context("Failed to parse JSON data as UTF-8")?; - let json_value: serde_json::Value = - serde_json::from_str(&json_str).context("Failed to parse JSON data")?; - cache_lock.put(key.clone(), serde_json::to_vec(&json_value)?); - } else { - cache_lock.put(key.clone(), data); - } + cache_lock.put(key.clone(), data); } drop(cache_lock); diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index e260ff2ca..dc8d56ab0 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -1,5 +1,5 @@ -use tokio::sync::Mutex; use anyhow::Result; +use tokio::sync::Mutex; pub fn get_key(sql: &str, command: &str) -> String { use sha2::{Digest, Sha256}; @@ -21,18 +21,17 @@ where Fut: std::future::Future>>, { let key = get_key(sql, command); - let mut cache_lock = cache.lock().await; - if let Some(cached) = cache_lock.get(&key) { + + if let Some(cached) = cache.lock().await.get(&key) { tracing::debug!("Cache hit {}!", key); - Ok(cached.clone()) - } else if persist { - let result = f().await?; - cache_lock.put(key, result.clone()); - Ok(result) - } else { - // no need to keep the cache lock if we are not storing anything - drop(cache_lock); - let result = f().await?; - Ok(result) + return Ok(cached.clone()); } + + let result = f().await?; + + if persist { + cache.lock().await.put(key, result.clone()); + } + + Ok(result) } diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index ee04d2d51..e2e29e98e 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,6 +1,6 @@ use anyhow::Result; use async_trait::async_trait; -use duckdb::{arrow::array::RecordBatch, Connection}; +use duckdb::Connection; use std::sync::Arc; use tokio::sync::Mutex; diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index a460cc505..ae6b9297f 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -93,12 +93,14 @@ async fn handle_query( "arrow" => { if let Some(sql) = params.sql.as_deref() { let persist = params.persist.unwrap_or(true); - let buffer = retrieve(&state.cache, sql, command, persist, || state.db.get_arrow_bytes(sql)) - .await - .map_err(|e| { - tracing::error!("Arrow retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let buffer = retrieve(&state.cache, sql, command, persist, || { + state.db.get_arrow_bytes(sql) + }) + .await + .map_err(|e| { + tracing::error!("Arrow retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; Ok(QueryResponse::Arrow(buffer)) } else { Err(StatusCode::BAD_REQUEST) @@ -107,12 +109,14 @@ async fn handle_query( "json" => { if let Some(sql) = params.sql.as_deref() { let persist = params.persist.unwrap_or(true); - let json: Vec = retrieve(&state.cache, sql, command, persist, || state.db.get_json(sql)) - .await - .map_err(|e| { - tracing::error!("JSON retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let json: Vec = retrieve(&state.cache, sql, command, persist, || { + state.db.get_json(sql) + }) + .await + .map_err(|e| { + tracing::error!("JSON retrieval error: {:?}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; let string = String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(QueryResponse::Json(string)) From 76c9701708e7e7732576fc2c718b6437e29e9bb7 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:36:30 -0400 Subject: [PATCH 22/66] rust checks --- packages/duckdb-server-rust/Cargo.lock | 3 ++ packages/duckdb-server-rust/Cargo.toml | 5 +++ packages/duckdb-server-rust/src/main.rs | 44 ++++++++++++--------- packages/duckdb-server-rust/src/test.rs | 52 +++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 packages/duckdb-server-rust/src/test.rs diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 4b9926169..e251b4f62 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -725,13 +725,16 @@ dependencies = [ "axum", "axum-server", "duckdb", + "http-body-util", "listenfd", "lru", + "mime", "regex", "serde", "serde_json", "sha2", "tokio", + "tower", "tower-http", "tracing", "tracing-subscriber", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 249e3f517..944644e48 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -22,3 +22,8 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } async-trait = "0.1.80" regex = "1.5" sha2 = "0.10" +mime = "0.3" + +[dev-dependencies] +tower = { version = "0.4", features = ["util"] } +http-body-util = "0.1.0" diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index ae6b9297f..fa823b6d4 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -34,8 +34,8 @@ struct AppState { cache: Mutex>>, } -#[derive(Deserialize, Serialize, Debug)] -struct QueryParams { +#[derive(Deserialize, Serialize, Debug, Default)] +pub struct QueryParams { #[serde(rename = "type")] query_type: String, persist: Option, @@ -55,13 +55,13 @@ impl IntoResponse for QueryResponse { match self { QueryResponse::Json(value) => ( StatusCode::OK, - [("Content-Type", "application/json")], + [("Content-Type", mime::APPLICATION_JSON.as_ref())], value, ) .into_response(), QueryResponse::Arrow(bytes) => ( StatusCode::OK, - [("Content-Type", "application/octet-stream")], + [("Content-Type", mime::APPLICATION_OCTET_STREAM.as_ref())], Bytes::from(bytes), ) .into_response(), @@ -171,18 +171,7 @@ async fn handle_post( handle_query(State(state), params).await } -#[tokio::main] -async fn main() -> Result<(), Box> { - // Tracing setup - tracing_subscriber::registry() - .with( - tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { - "duckdb_server_rust=debug,tower_http=debug,axum::rejection=trace".into() - }), - ) - .with(tracing_subscriber::fmt::layer()) - .init(); - +pub fn app() -> Result { // Database and state setup let con = Connection::open_in_memory()?; let db = Arc::new(DuckDbDatabase::new(con)); @@ -201,10 +190,26 @@ async fn main() -> Result<(), Box> { .max_age(Duration::from_secs(60) * 60 * 24); // Router setup - let app = Router::new() + Ok(Router::new() .route("/", get(handle_get).post(handle_post)) .with_state(state) - .layer(cors); + .layer(cors)) +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Tracing setup + tracing_subscriber::registry() + .with( + tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { + "duckdb_server_rust=debug,tower_http=debug,axum::rejection=trace".into() + }), + ) + .with(tracing_subscriber::fmt::layer()) + .init(); + + // App setup + let app = app()?; // TLS configuration let config = RustlsConfig::from_pem_file( @@ -238,3 +243,6 @@ async fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(test)] +mod test; diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs new file mode 100644 index 000000000..66d466c6f --- /dev/null +++ b/packages/duckdb-server-rust/src/test.rs @@ -0,0 +1,52 @@ +use super::*; +use axum::{ + body::Body, + http::{self, Request, StatusCode}, +}; +use http_body_util::BodyExt; +use serde_json::json; +use tower::ServiceExt; + +#[tokio::test] +async fn select_1_get() { + let app = app().unwrap(); + + let response = app + .oneshot( + Request::builder() + .uri("/?type=json&sql=SELECT%201%20as%20foo") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + let body = response.into_body().collect().await.unwrap().to_bytes(); + assert_eq!(&body[..], b"[{\"foo\":1}]"); +} + +#[tokio::test] +async fn select_1_post() { + let app = app().unwrap(); + + let response = app + .oneshot( + Request::builder() + .method(http::Method::POST) + .uri("/") + .header(http::header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref()) + .body(Body::from( + serde_json::to_vec(&json!({"type": "json", "sql": "select 1 as foo"})).unwrap() + )) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + let body = response.into_body().collect().await.unwrap().to_bytes(); + assert_eq!(&body[..], b"[{\"foo\":1}]"); +} From 500262b3f3ee1d6e6f98751f1f2c5b84de149b4c Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:40:12 -0400 Subject: [PATCH 23/66] rust tests --- .github/workflows/test.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d61c13e3..14dc96ee7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,3 +64,23 @@ jobs: hatch build hatch fmt --check hatch run test:cov + + rust: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rust-src, rustfmt + - name: Check formatting + run: cargo fmt -- --check + - name: Check + run: cargo check + - name: Clippy + run: cargo clippy --all -- -D warnings + - name: Build + run: cargo build --verbose + - name: Test + run: cargo test --verbose From d1394e463fd30b3e5588d33b5131efecc0152b71 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:42:36 -0400 Subject: [PATCH 24/66] update test names --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 14dc96ee7..375e21216 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: - run: npm run test python: - name: Test on Python + name: Test in Python runs-on: ubuntu-latest @@ -66,6 +66,8 @@ jobs: hatch run test:cov rust: + name: Test in Rust + runs-on: ubuntu-latest steps: From e4c17b6121be20e582dce9a58969718dce10161b Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:44:06 -0400 Subject: [PATCH 25/66] tests --- .github/workflows/test.yml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 375e21216..42ab2e38b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,13 +76,24 @@ jobs: uses: dtolnay/rust-toolchain@stable with: components: clippy, rust-src, rustfmt + - name: Check formatting - run: cargo fmt -- --check + run: | + cd packages/duckdb-server-rust + cargo fmt -- --check - name: Check - run: cargo check + run: | + cd packages/duckdb-server-rust + cargo check - name: Clippy - run: cargo clippy --all -- -D warnings + run: | + cd packages/duckdb-server-rust + cargo clippy --all -- -D warnings - name: Build - run: cargo build --verbose + run: | + cd packages/duckdb-server-rust + cargo build --verbose - name: Test - run: cargo test --verbose + run: | + cd packages/duckdb-server-rust + cargo test --verbose From ffbbf2f419b8311db4f12447e63a1a802d640108 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:47:26 -0400 Subject: [PATCH 26/66] format --- packages/duckdb-server-rust/src/bundle.rs | 3 ++- packages/duckdb-server-rust/src/test.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 4731a8121..5b9d6d8e0 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -79,7 +79,8 @@ pub async fn create_bundle( } else { db.get_json(sql) } - }).await?; + }) + .await?; fs::write(bundle_dir.join(&key), &result) .context("Failed to write query result to file")?; manifest.queries.push(key); diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index 66d466c6f..eccbe7e05 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -38,7 +38,7 @@ async fn select_1_post() { .uri("/") .header(http::header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref()) .body(Body::from( - serde_json::to_vec(&json!({"type": "json", "sql": "select 1 as foo"})).unwrap() + serde_json::to_vec(&json!({"type": "json", "sql": "select 1 as foo"})).unwrap(), )) .unwrap(), ) From edc5f27c8923de26672e5a578497ccfaeabda2e1 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 17:56:29 -0400 Subject: [PATCH 27/66] clippy --- packages/duckdb-server-rust/src/bundle.rs | 10 +++++----- packages/duckdb-server-rust/src/main.rs | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 5b9d6d8e0..78b09019f 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -19,7 +19,7 @@ pub struct Query { alias: Option, } -pub async fn create_bundle( +pub async fn create( db: &dyn Database, cache: &Mutex>>, queries: Vec, @@ -41,7 +41,7 @@ pub async fn create_bundle( let sql = &query.sql; if let Some(alias) = &query.alias { - let file = bundle_dir.join(format!("{}.parquet", alias)); + let file = bundle_dir.join(format!("{alias}.parquet")); db.execute(&format!( "COPY ({}) TO '{}' (FORMAT PARQUET)", sql, @@ -56,7 +56,7 @@ pub async fn create_bundle( if let Some(captures) = table_re.captures(sql) { let table = captures.get(3).unwrap().as_str(); - let file = bundle_dir.join(format!("{}.parquet", table)); + let file = bundle_dir.join(format!("{table}.parquet")); db.execute(sql).await?; db.execute(&format!( "COPY {} TO '{}' (FORMAT PARQUET)", @@ -95,7 +95,7 @@ pub async fn create_bundle( Ok(manifest) } -pub async fn load_bundle( +pub async fn load( db: &dyn Database, cache: &Mutex>>, bundle_dir: &Path, @@ -118,7 +118,7 @@ pub async fn load_bundle( // Load precomputed temp tables into the database for table in &manifest.tables { - let file = bundle_dir.join(format!("{}.parquet", table)); + let file = bundle_dir.join(format!("{table}.parquet")); db.execute(&format!( "CREATE TEMP TABLE IF NOT EXISTS {} AS SELECT * FROM '{}'", table, diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index fa823b6d4..0d0b69e7e 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -25,7 +25,7 @@ mod bundle; mod cache; mod db; -use bundle::{create_bundle, load_bundle, Query as BundleQuery}; +use bundle::{create, load, Query as BundleQuery}; use cache::retrieve; use db::{Database, DuckDbDatabase}; @@ -128,7 +128,7 @@ async fn handle_query( if let Some(queries) = params.queries { let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - create_bundle(state.db.as_ref(), &state.cache, queries, &bundle_path) + create(state.db.as_ref(), &state.cache, queries, &bundle_path) .await .map_err(|e| { tracing::error!("Bundle creation error: {:?}", e); @@ -142,7 +142,7 @@ async fn handle_query( "load-bundle" => { if let Some(bundle_name) = params.name { let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - load_bundle(state.db.as_ref(), &state.cache, &bundle_path) + load(state.db.as_ref(), &state.cache, &bundle_path) .await .map_err(|e| { tracing::error!("Bundle loading error: {:?}", e); @@ -175,7 +175,7 @@ pub fn app() -> Result { // Database and state setup let con = Connection::open_in_memory()?; let db = Arc::new(DuckDbDatabase::new(con)); - let cache = lru::LruCache::new(1000.try_into().unwrap()); + let cache = lru::LruCache::new(1000.try_into()?); let state = Arc::new(AppState { db, From 32a708eace7bdbe7efc685b0951d6bc07786b7b4 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 7 Jul 2024 18:51:34 -0400 Subject: [PATCH 28/66] Add compression and tracing --- packages/duckdb-server-rust/Cargo.lock | 85 +++++++++++++++++++++++++ packages/duckdb-server-rust/Cargo.toml | 2 +- packages/duckdb-server-rust/src/main.rs | 5 +- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index e251b4f62..6f66e8cd0 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -51,6 +51,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -309,6 +324,22 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "async-compression" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd", + "zstd-safe", +] + [[package]] name = "async-trait" version = "0.1.80" @@ -506,6 +537,27 @@ dependencies = [ "syn_derive", ] +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -2229,14 +2281,19 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ + "async-compression", "bitflags 2.6.0", "bytes", + "futures-core", "http", "http-body", "http-body-util", "pin-project-lite", + "tokio", + "tokio-util", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -2690,3 +2747,31 @@ dependencies = [ "quote", "syn 2.0.69", ] + +[[package]] +name = "zstd" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 944644e48..769742e4f 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -10,7 +10,7 @@ duckdb = { version = "0.10", features = ["bundled", "csv", "json", "parquet", "u axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing"] } axum-server = { version = "0.6", features = ["tls-rustls"] } tokio = { version = "1", features = ["full"] } -tower-http = { version = "0.5.0", features = ["cors"] } +tower-http = { version = "0.5.0", features = ["cors", "compression-full", "trace"] } listenfd = "1.0.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 0d0b69e7e..299889f52 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -19,6 +19,7 @@ use std::time::Duration; use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; use tokio::sync::Mutex; use tower_http::cors::{Any, CorsLayer}; +use tower_http::{compression::CompressionLayer, trace::TraceLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod bundle; @@ -193,7 +194,9 @@ pub fn app() -> Result { Ok(Router::new() .route("/", get(handle_get).post(handle_post)) .with_state(state) - .layer(cors)) + .layer(cors) + .layer(CompressionLayer::new()) + .layer(TraceLayer::new_for_http())) } #[tokio::main] From ca70b304891e6167593333b9a8e0a2fb59f9b490 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 8 Jul 2024 08:55:18 -0400 Subject: [PATCH 29/66] Https and https --- packages/duckdb-server-rust/Cargo.lock | 19 +++++++++++++++++++ packages/duckdb-server-rust/Cargo.toml | 1 + packages/duckdb-server-rust/src/main.rs | 2 +- packages/plot/src/marks/ConnectedMark.js | 2 +- packages/plot/src/marks/util/stats.js | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 6f66e8cd0..7df1355fb 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -453,6 +453,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-server-dual-protocol" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea4cd08ae2a5f075d28fa31190163c8106a1d2d3189442494bae22b39040a0d" +dependencies = [ + "axum-server", + "bytes", + "http", + "http-body-util", + "pin-project", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.73" @@ -776,6 +794,7 @@ dependencies = [ "async-trait", "axum", "axum-server", + "axum-server-dual-protocol", "duckdb", "http-body-util", "listenfd", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 769742e4f..954388a32 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -23,6 +23,7 @@ async-trait = "0.1.80" regex = "1.5" sha2 = "0.10" mime = "0.3" +axum-server-dual-protocol = "0.6" [dev-dependencies] tower = { version = "0.4", features = ["util"] } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 299889f52..400293af7 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -240,7 +240,7 @@ async fn main() -> Result<(), Box> { "DuckDB Server listening on https://{}", listener.local_addr().unwrap() ); - axum_server::from_tcp_rustls(listener, config) + axum_server_dual_protocol::from_tcp_dual_protocol(listener, config) .serve(app.into_make_service()) .await?; diff --git a/packages/plot/src/marks/ConnectedMark.js b/packages/plot/src/marks/ConnectedMark.js index 44247688c..b9cb427ff 100644 --- a/packages/plot/src/marks/ConnectedMark.js +++ b/packages/plot/src/marks/ConnectedMark.js @@ -45,7 +45,7 @@ export class ConnectedMark extends Mark { /** * M4 is an optimization for value-preserving time-series aggregation - * (http://www.vldb.org/pvldb/vol7/p797-jugel.pdf). This implementation uses + * (https://www.vldb.org/pvldb/vol7/p797-jugel.pdf). This implementation uses * an efficient version with a single scan and the aggregate function * argmin and argmax, following https://arxiv.org/pdf/2306.03714.pdf. */ diff --git a/packages/plot/src/marks/util/stats.js b/packages/plot/src/marks/util/stats.js index 9b70e7076..7970947cc 100644 --- a/packages/plot/src/marks/util/stats.js +++ b/packages/plot/src/marks/util/stats.js @@ -172,7 +172,7 @@ export function qt(p, dof) { export function erfinv(x) { // Implementation from "Approximating the erfinv function" by Mike Giles, // GPU Computing Gems, volume 2, 2010. - // Ported from Apache Commons Math, http://www.apache.org/licenses/LICENSE-2.0 + // Ported from Apache Commons Math, https://www.apache.org/licenses/LICENSE-2.0 // beware that the logarithm argument must be // computed as (1.0 - x) * (1.0 + x), From 431e166e57716a226082c1f5f94b855f122f85dc Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 12 Jul 2024 09:12:20 -0400 Subject: [PATCH 30/66] refactor and add ws support --- packages/duckdb-server-rust/Cargo.lock | 49 ++++++ packages/duckdb-server-rust/Cargo.toml | 1 + packages/duckdb-server-rust/src/interfaces.rs | 95 +++++++++++ packages/duckdb-server-rust/src/main.rs | 160 +++--------------- packages/duckdb-server-rust/src/query.rs | 92 ++++++++++ packages/duckdb-server-rust/src/websocket.rs | 30 ++++ 6 files changed, 290 insertions(+), 137 deletions(-) create mode 100644 packages/duckdb-server-rust/src/interfaces.rs create mode 100644 packages/duckdb-server-rust/src/query.rs create mode 100644 packages/duckdb-server-rust/src/websocket.rs diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 7df1355fb..7c6478a54 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -796,6 +796,7 @@ dependencies = [ "axum-server", "axum-server-dual-protocol", "duckdb", + "futures", "http-body-util", "listenfd", "lru", @@ -892,6 +893,21 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -899,6 +915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -907,6 +924,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -925,9 +970,13 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 954388a32..832a9e263 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -24,6 +24,7 @@ regex = "1.5" sha2 = "0.10" mime = "0.3" axum-server-dual-protocol = "0.6" +futures = "0.3" [dev-dependencies] tower = { version = "0.4", features = ["util"] } diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs new file mode 100644 index 000000000..99657c0fe --- /dev/null +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -0,0 +1,95 @@ +use anyhow::{Context, Result}; +use axum::{ + body::Bytes, + extract::{Query, State, WebSocketUpgrade}, + http::{Method, StatusCode}, + response::{IntoResponse, Json, Response}, + routing::get, + Router, +}; +use axum_server::tls_rustls::RustlsConfig; +use duckdb::Connection; +use listenfd::ListenFd; +use serde::{Deserialize, Serialize}; +use std::net::TcpListener; +use std::path::Path; +use std::sync::Arc; +use std::time::Duration; +use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; +use tokio::sync::Mutex; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::{compression::CompressionLayer, trace::TraceLayer}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + +use crate::bundle::{create, load, Query as BundleQuery}; +use crate::cache::retrieve; +use crate::db::{Database, DuckDbDatabase}; +use crate::query::handle_query; +use crate::websocket::handle_websocket; + +pub struct AppState { + pub db: Arc, + pub cache: Mutex>>, +} + +#[derive(Deserialize, Serialize, Debug, Default)] +pub struct QueryParams { + #[serde(rename = "type")] + pub query_type: String, + pub persist: Option, + pub sql: Option, + pub name: Option, + pub queries: Option>, +} + +pub enum QueryResponse { + Json(String), + Arrow(Vec), + WebSocket(Response), + BadRequest, + Empty, +} + +impl IntoResponse for QueryResponse { + fn into_response(self) -> Response { + match self { + QueryResponse::Json(value) => ( + StatusCode::OK, + [("Content-Type", mime::APPLICATION_JSON.as_ref())], + value, + ) + .into_response(), + QueryResponse::Arrow(bytes) => ( + StatusCode::OK, + [("Content-Type", mime::APPLICATION_OCTET_STREAM.as_ref())], + Bytes::from(bytes), + ) + .into_response(), + QueryResponse::WebSocket(response) => response, + QueryResponse::BadRequest => StatusCode::BAD_REQUEST.into_response(), + QueryResponse::Empty => StatusCode::OK.into_response(), + } + } +} + +pub struct AppError(anyhow::Error); + +impl IntoResponse for AppError { + fn into_response(self) -> Response { + tracing::error!("Error: {:?}", self.0); + ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Something went wrong: {}", self.0), + ) + .into_response() + } +} + +impl From for AppError +where + E: Into, +{ + fn from(err: E) -> Self { + Self(err.into()) + } +} diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 400293af7..4840be4f9 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,9 +1,8 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use axum::{ body::Bytes, - extract::{Query, State}, - http::Method, - http::StatusCode, + extract::{Query, State, WebSocketUpgrade}, + http::{Method, StatusCode}, response::{IntoResponse, Json, Response}, routing::get, Router, @@ -25,151 +24,38 @@ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod bundle; mod cache; mod db; +mod interfaces; +mod query; +mod websocket; use bundle::{create, load, Query as BundleQuery}; use cache::retrieve; use db::{Database, DuckDbDatabase}; - -struct AppState { - db: Arc, - cache: Mutex>>, -} - -#[derive(Deserialize, Serialize, Debug, Default)] -pub struct QueryParams { - #[serde(rename = "type")] - query_type: String, - persist: Option, - sql: Option, - name: Option, - queries: Option>, -} - -enum QueryResponse { - Json(String), - Arrow(Vec), - Empty, -} - -impl IntoResponse for QueryResponse { - fn into_response(self) -> Response { - match self { - QueryResponse::Json(value) => ( - StatusCode::OK, - [("Content-Type", mime::APPLICATION_JSON.as_ref())], - value, - ) - .into_response(), - QueryResponse::Arrow(bytes) => ( - StatusCode::OK, - [("Content-Type", mime::APPLICATION_OCTET_STREAM.as_ref())], - Bytes::from(bytes), - ) - .into_response(), - QueryResponse::Empty => StatusCode::OK.into_response(), - } - } -} - -async fn handle_query( - State(state): State>, - params: QueryParams, -) -> Result { - let command = ¶ms.query_type; - tracing::info!("Command: '{}', Params: '{:?}'", command, params); - - match command.as_str() { - "exec" => { - if let Some(sql) = params.sql.as_deref() { - state - .db - .execute(sql) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - Ok(QueryResponse::Empty) - } else { - Err(StatusCode::BAD_REQUEST) - } - } - "arrow" => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let buffer = retrieve(&state.cache, sql, command, persist, || { - state.db.get_arrow_bytes(sql) - }) - .await - .map_err(|e| { - tracing::error!("Arrow retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(QueryResponse::Arrow(buffer)) - } else { - Err(StatusCode::BAD_REQUEST) - } - } - "json" => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let json: Vec = retrieve(&state.cache, sql, command, persist, || { - state.db.get_json(sql) - }) - .await - .map_err(|e| { - tracing::error!("JSON retrieval error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - let string = - String::from_utf8(json).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - Ok(QueryResponse::Json(string)) - } else { - Err(StatusCode::BAD_REQUEST) - } - } - "create-bundle" => { - if let Some(queries) = params.queries { - let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - create(state.db.as_ref(), &state.cache, queries, &bundle_path) - .await - .map_err(|e| { - tracing::error!("Bundle creation error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(QueryResponse::Empty) - } else { - Err(StatusCode::BAD_REQUEST) - } - } - "load-bundle" => { - if let Some(bundle_name) = params.name { - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - load(state.db.as_ref(), &state.cache, &bundle_path) - .await - .map_err(|e| { - tracing::error!("Bundle loading error: {:?}", e); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(QueryResponse::Empty) - } else { - Err(StatusCode::BAD_REQUEST) - } - } - _ => Err(StatusCode::BAD_REQUEST), - } -} +use interfaces::{AppError, AppState, QueryParams, QueryResponse}; +use query::handle_query; +use websocket::handle_websocket; async fn handle_get( State(state): State>, - Query(params): Query, -) -> Result { - handle_query(State(state), params).await + ws: Option, + Query(params): Query +) -> Result { + if let Some(ws) = ws { + // WebSocket upgrade + Ok(QueryResponse::WebSocket( + ws.on_upgrade(|socket| handle_websocket(socket, state)), + )) + } else { + // HTTP request + handle_query(state, params).await + } } async fn handle_post( State(state): State>, Json(params): Json, -) -> Result { - handle_query(State(state), params).await +) -> Result { + handle_query(state, params).await } pub fn app() -> Result { diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs new file mode 100644 index 000000000..9460f532a --- /dev/null +++ b/packages/duckdb-server-rust/src/query.rs @@ -0,0 +1,92 @@ +use anyhow::{Context, Result}; +use axum::{ + body::Bytes, + extract::{Query, State, WebSocketUpgrade}, + http::{Method, StatusCode}, + response::{IntoResponse, Json, Response}, + routing::get, + Router, +}; +use axum_server::tls_rustls::RustlsConfig; +use duckdb::Connection; +use listenfd::ListenFd; +use serde::{Deserialize, Serialize}; +use std::net::TcpListener; +use std::path::Path; +use std::sync::Arc; +use std::time::Duration; +use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; +use tokio::sync::Mutex; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::{compression::CompressionLayer, trace::TraceLayer}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + +use crate::bundle::{create, load, Query as BundleQuery}; +use crate::cache::retrieve; +use crate::db::{Database, DuckDbDatabase}; +use crate::interfaces::{AppError, AppState, QueryParams, QueryResponse}; +use crate::websocket::handle_websocket; + +pub async fn handle_query( + state: Arc, + params: QueryParams, +) -> Result { + let command = ¶ms.query_type; + tracing::info!("Command: '{}', Params: '{:?}'", command, params); + + match command.as_str() { + "exec" => { + if let Some(sql) = params.sql.as_deref() { + state.db.execute(sql).await?; + Ok(QueryResponse::Empty) + } else { + Ok(QueryResponse::BadRequest) + } + } + "arrow" => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let buffer = retrieve(&state.cache, sql, command, persist, || { + state.db.get_arrow_bytes(sql) + }) + .await?; + Ok(QueryResponse::Arrow(buffer)) + } else { + Ok(QueryResponse::BadRequest) + } + } + "json" => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let json: Vec = retrieve(&state.cache, sql, command, persist, || { + state.db.get_json(sql) + }) + .await?; + let string = String::from_utf8(json)?; + Ok(QueryResponse::Json(string)) + } else { + Ok(QueryResponse::BadRequest) + } + } + "create-bundle" => { + if let Some(queries) = params.queries { + let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Ok(QueryResponse::BadRequest) + } + } + "load-bundle" => { + if let Some(bundle_name) = params.name { + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + load(state.db.as_ref(), &state.cache, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Ok(QueryResponse::BadRequest) + } + } + _ => Ok(QueryResponse::BadRequest), + } +} diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs new file mode 100644 index 000000000..5a1a9db52 --- /dev/null +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -0,0 +1,30 @@ +use crate::AppState; +use axum::extract::ws::{Message, WebSocket}; +use futures::{SinkExt, StreamExt}; +use std::sync::Arc; + +pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { + while let Some(msg) = socket.recv().await { + if let Ok(msg) = msg { + match msg { + Message::Text(text) => { + // Handle text messages + let response = handle_websocket_message(text, &state).await; + if socket.send(Message::Text(response)).await.is_err() { + break; + } + } + Message::Close(_) => break, + _ => {} + } + } else { + break; + } + } +} + +async fn handle_websocket_message(message: String, state: &Arc) -> String { + // Implement your WebSocket message handling logic here + // You can use state.db and state.cache as needed + format!("Received: {}", message) +} From 94f543edc5bf01b90fa246e47c528df84d042b5b Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 12 Jul 2024 09:14:39 -0400 Subject: [PATCH 31/66] clean up --- packages/duckdb-server-rust/src/interfaces.rs | 25 +++---------------- packages/duckdb-server-rust/src/main.rs | 15 ++++------- packages/duckdb-server-rust/src/query.rs | 25 ++----------------- packages/duckdb-server-rust/src/websocket.rs | 2 +- 4 files changed, 12 insertions(+), 55 deletions(-) diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 99657c0fe..996c2140d 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -1,31 +1,14 @@ -use anyhow::{Context, Result}; use axum::{ body::Bytes, - extract::{Query, State, WebSocketUpgrade}, - http::{Method, StatusCode}, - response::{IntoResponse, Json, Response}, - routing::get, - Router, + http::StatusCode, + response::{IntoResponse, Response}, }; -use axum_server::tls_rustls::RustlsConfig; -use duckdb::Connection; -use listenfd::ListenFd; use serde::{Deserialize, Serialize}; -use std::net::TcpListener; -use std::path::Path; use std::sync::Arc; -use std::time::Duration; -use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; use tokio::sync::Mutex; -use tower_http::cors::{Any, CorsLayer}; -use tower_http::{compression::CompressionLayer, trace::TraceLayer}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use crate::bundle::{create, load, Query as BundleQuery}; -use crate::cache::retrieve; -use crate::db::{Database, DuckDbDatabase}; -use crate::query::handle_query; -use crate::websocket::handle_websocket; +use crate::bundle::Query as BundleQuery; +use crate::db::Database; pub struct AppState { pub db: Arc, diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 4840be4f9..438de5d16 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,18 +1,15 @@ -use anyhow::{Context, Result}; +use anyhow::Result; use axum::{ - body::Bytes, extract::{Query, State, WebSocketUpgrade}, - http::{Method, StatusCode}, - response::{IntoResponse, Json, Response}, + http::Method, + response::Json, routing::get, Router, }; use axum_server::tls_rustls::RustlsConfig; use duckdb::Connection; use listenfd::ListenFd; -use serde::{Deserialize, Serialize}; use std::net::TcpListener; -use std::path::Path; use std::sync::Arc; use std::time::Duration; use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; @@ -28,9 +25,7 @@ mod interfaces; mod query; mod websocket; -use bundle::{create, load, Query as BundleQuery}; -use cache::retrieve; -use db::{Database, DuckDbDatabase}; +use db::DuckDbDatabase; use interfaces::{AppError, AppState, QueryParams, QueryResponse}; use query::handle_query; use websocket::handle_websocket; @@ -38,7 +33,7 @@ use websocket::handle_websocket; async fn handle_get( State(state): State>, ws: Option, - Query(params): Query + Query(params): Query, ) -> Result { if let Some(ws) = ws { // WebSocket upgrade diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index 9460f532a..24b452ff5 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -1,31 +1,10 @@ -use anyhow::{Context, Result}; -use axum::{ - body::Bytes, - extract::{Query, State, WebSocketUpgrade}, - http::{Method, StatusCode}, - response::{IntoResponse, Json, Response}, - routing::get, - Router, -}; -use axum_server::tls_rustls::RustlsConfig; -use duckdb::Connection; -use listenfd::ListenFd; -use serde::{Deserialize, Serialize}; -use std::net::TcpListener; +use anyhow::Result; use std::path::Path; use std::sync::Arc; -use std::time::Duration; -use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; -use tokio::sync::Mutex; -use tower_http::cors::{Any, CorsLayer}; -use tower_http::{compression::CompressionLayer, trace::TraceLayer}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use crate::bundle::{create, load, Query as BundleQuery}; +use crate::bundle::{create, load}; use crate::cache::retrieve; -use crate::db::{Database, DuckDbDatabase}; use crate::interfaces::{AppError, AppState, QueryParams, QueryResponse}; -use crate::websocket::handle_websocket; pub async fn handle_query( state: Arc, diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 5a1a9db52..2c22962a4 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -1,6 +1,6 @@ use crate::AppState; use axum::extract::ws::{Message, WebSocket}; -use futures::{SinkExt, StreamExt}; +use futures::SinkExt; use std::sync::Arc; pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { From 764e4fd9cf744a173c93a8b4a30b283fd059724d Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 12 Jul 2024 15:33:41 -0400 Subject: [PATCH 32/66] update and add socket --- packages/duckdb-server-rust/Cargo.lock | 1 - packages/duckdb-server-rust/Cargo.toml | 1 - packages/duckdb-server-rust/src/bundle.rs | 16 ++- packages/duckdb-server-rust/src/cache.rs | 10 +- packages/duckdb-server-rust/src/interfaces.rs | 46 ++++--- packages/duckdb-server-rust/src/main.rs | 2 +- packages/duckdb-server-rust/src/query.rs | 114 +++++++++--------- packages/duckdb-server-rust/src/test.rs | 2 +- packages/duckdb-server-rust/src/websocket.rs | 55 +++++++-- 9 files changed, 151 insertions(+), 96 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 7c6478a54..21794c905 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -800,7 +800,6 @@ dependencies = [ "http-body-util", "listenfd", "lru", - "mime", "regex", "serde", "serde_json", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 832a9e263..5516792c2 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -22,7 +22,6 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } async-trait = "0.1.80" regex = "1.5" sha2 = "0.10" -mime = "0.3" axum-server-dual-protocol = "0.6" futures = "0.3" diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 78b09019f..4883873ac 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -1,5 +1,6 @@ use crate::cache::{get_key, retrieve}; use crate::db::Database; +use crate::interfaces::Command; use anyhow::{Context, Result}; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -68,17 +69,14 @@ pub async fn create( } } else if !pragma_re.is_match(sql) { let command = if describe_re.is_match(sql) { - "json" + Command::Json } else { - "arrow" + Command::Arrow }; - let key = get_key(sql, command); - let result = retrieve(cache, sql, command, true, || { - if command == "arrow" { - db.get_arrow_bytes(sql) - } else { - db.get_json(sql) - } + let key = get_key(sql, &command); + let result = retrieve(cache, sql, &command, true, || match command { + Command::Arrow => db.get_arrow_bytes(sql), + _ => db.get_json(sql), }) .await?; fs::write(bundle_dir.join(&key), &result) diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index dc8d56ab0..15a8f9c0d 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -1,18 +1,20 @@ use anyhow::Result; +use serde_json::to_string; use tokio::sync::Mutex; -pub fn get_key(sql: &str, command: &str) -> String { +use crate::interfaces::Command; + +pub fn get_key(sql: &str, command: &Command) -> String { use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); hasher.update(sql); - hasher.update(command); - format!("{:x}.{}", hasher.finalize(), command) + format!("{:x}.{}", hasher.finalize(), to_string(&command).unwrap()) } pub async fn retrieve( cache: &Mutex>>, sql: &str, - command: &str, + command: &Command, persist: bool, f: F, ) -> Result> diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 996c2140d..cf855e4db 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -15,10 +15,20 @@ pub struct AppState { pub cache: Mutex>>, } +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub enum Command { + Exec, + Arrow, + Json, + CreateBundle, + LoadBundle, +} + #[derive(Deserialize, Serialize, Debug, Default)] pub struct QueryParams { #[serde(rename = "type")] - pub query_type: String, + pub query_type: Option, pub persist: Option, pub sql: Option, pub name: Option, @@ -28,8 +38,7 @@ pub struct QueryParams { pub enum QueryResponse { Json(String), Arrow(Vec), - WebSocket(Response), - BadRequest, + Response(Response), Empty, } @@ -38,33 +47,40 @@ impl IntoResponse for QueryResponse { match self { QueryResponse::Json(value) => ( StatusCode::OK, - [("Content-Type", mime::APPLICATION_JSON.as_ref())], + [("Content-Type", "application/json")], value, ) .into_response(), QueryResponse::Arrow(bytes) => ( StatusCode::OK, - [("Content-Type", mime::APPLICATION_OCTET_STREAM.as_ref())], + [("Content-Type", "application/vnd.apache.arrow.stream")], Bytes::from(bytes), ) .into_response(), - QueryResponse::WebSocket(response) => response, - QueryResponse::BadRequest => StatusCode::BAD_REQUEST.into_response(), + QueryResponse::Response(response) => response, QueryResponse::Empty => StatusCode::OK.into_response(), } } } -pub struct AppError(anyhow::Error); +pub enum AppError { + Error(anyhow::Error), + BadRequest, +} impl IntoResponse for AppError { fn into_response(self) -> Response { - tracing::error!("Error: {:?}", self.0); - ( - StatusCode::INTERNAL_SERVER_ERROR, - format!("Something went wrong: {}", self.0), - ) - .into_response() + match self { + AppError::Error(error) => { + tracing::error!("Error: {:?}", error); + ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Something went wrong: {}", error), + ) + .into_response() + } + AppError::BadRequest => (StatusCode::BAD_REQUEST).into_response(), + } } } @@ -73,6 +89,6 @@ where E: Into, { fn from(err: E) -> Self { - Self(err.into()) + AppError::Error(err.into()) } } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 438de5d16..e624cca1a 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -37,7 +37,7 @@ async fn handle_get( ) -> Result { if let Some(ws) = ws { // WebSocket upgrade - Ok(QueryResponse::WebSocket( + Ok(QueryResponse::Response( ws.on_upgrade(|socket| handle_websocket(socket, state)), )) } else { diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index 24b452ff5..1017fffb0 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -4,68 +4,72 @@ use std::sync::Arc; use crate::bundle::{create, load}; use crate::cache::retrieve; -use crate::interfaces::{AppError, AppState, QueryParams, QueryResponse}; +use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; pub async fn handle_query( state: Arc, params: QueryParams, ) -> Result { - let command = ¶ms.query_type; - tracing::info!("Command: '{}', Params: '{:?}'", command, params); + match ¶ms.query_type { + None => Err(AppError::BadRequest), + Some(query_command) => { + tracing::info!("Command: '{:?}', Params: '{:?}'", query_command, params); - match command.as_str() { - "exec" => { - if let Some(sql) = params.sql.as_deref() { - state.db.execute(sql).await?; - Ok(QueryResponse::Empty) - } else { - Ok(QueryResponse::BadRequest) + match query_command { + Command::Exec => { + if let Some(sql) = params.sql.as_deref() { + state.db.execute(sql).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } + Command::Arrow => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let buffer = retrieve(&state.cache, sql, query_command, persist, || { + state.db.get_arrow_bytes(sql) + }) + .await?; + Ok(QueryResponse::Arrow(buffer)) + } else { + Err(AppError::BadRequest) + } + } + Command::Json => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let json: Vec = + retrieve(&state.cache, sql, query_command, persist, || { + state.db.get_json(sql) + }) + .await?; + let string = String::from_utf8(json)?; + Ok(QueryResponse::Json(string)) + } else { + Err(AppError::BadRequest) + } + } + Command::CreateBundle => { + if let Some(queries) = params.queries { + let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } + Command::LoadBundle => { + if let Some(bundle_name) = params.name { + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + load(state.db.as_ref(), &state.cache, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } } } - "arrow" => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let buffer = retrieve(&state.cache, sql, command, persist, || { - state.db.get_arrow_bytes(sql) - }) - .await?; - Ok(QueryResponse::Arrow(buffer)) - } else { - Ok(QueryResponse::BadRequest) - } - } - "json" => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let json: Vec = retrieve(&state.cache, sql, command, persist, || { - state.db.get_json(sql) - }) - .await?; - let string = String::from_utf8(json)?; - Ok(QueryResponse::Json(string)) - } else { - Ok(QueryResponse::BadRequest) - } - } - "create-bundle" => { - if let Some(queries) = params.queries { - let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; - Ok(QueryResponse::Empty) - } else { - Ok(QueryResponse::BadRequest) - } - } - "load-bundle" => { - if let Some(bundle_name) = params.name { - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - load(state.db.as_ref(), &state.cache, &bundle_path).await?; - Ok(QueryResponse::Empty) - } else { - Ok(QueryResponse::BadRequest) - } - } - _ => Ok(QueryResponse::BadRequest), } } diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index eccbe7e05..6d5bb43b4 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -36,7 +36,7 @@ async fn select_1_post() { Request::builder() .method(http::Method::POST) .uri("/") - .header(http::header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref()) + .header(http::header::CONTENT_TYPE, "application/json") .body(Body::from( serde_json::to_vec(&json!({"type": "json", "sql": "select 1 as foo"})).unwrap(), )) diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 2c22962a4..425db4017 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -1,6 +1,10 @@ -use crate::AppState; +use crate::{ + interfaces::{AppError, QueryResponse}, + query::handle_query, + AppState, +}; use axum::extract::ws::{Message, WebSocket}; -use futures::SinkExt; +use serde_json::json; use std::sync::Arc; pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { @@ -8,9 +12,43 @@ pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { if let Ok(msg) = msg { match msg { Message::Text(text) => { - // Handle text messages - let response = handle_websocket_message(text, &state).await; - if socket.send(Message::Text(response)).await.is_err() { + let response = handle_message(text, state.clone()).await; + if match response { + Err(error) => match error { + AppError::BadRequest => { + socket + .send(Message::Text( + json!({"error": "Bad request"}).to_string(), + )) + .await + } + AppError::Error(error) => { + socket + .send(Message::Text( + json!({"error": format!("{}", error)}).to_string(), + )) + .await + } + }, + Ok(result) => match result { + QueryResponse::Arrow(arrow) => { + socket.send(Message::Binary(arrow)).await + } + QueryResponse::Json(json) => socket.send(Message::Text(json)).await, + QueryResponse::Empty => { + socket.send(Message::Text("{}".to_string())).await + } + _ => { + socket + .send(Message::Text( + json!({"error": "Unknown response Type"}).to_string(), + )) + .await + } + }, + } + .is_err() + { break; } } @@ -23,8 +61,7 @@ pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { } } -async fn handle_websocket_message(message: String, state: &Arc) -> String { - // Implement your WebSocket message handling logic here - // You can use state.db and state.cache as needed - format!("Received: {}", message) +async fn handle_message(message: String, state: Arc) -> Result { + let params = serde_json::from_str(&message)?; + handle_query(state, params).await } From 44420158f6f2dd3c41c936b3f21e0907d6c7e513 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 12 Jul 2024 15:45:44 -0400 Subject: [PATCH 33/66] update deps and fix lint issues --- packages/duckdb-server-rust/Cargo.lock | 145 +++++++++--------- packages/duckdb-server-rust/Cargo.toml | 24 +-- packages/duckdb-server-rust/src/interfaces.rs | 2 +- packages/duckdb-server-rust/src/main.rs | 10 +- packages/duckdb-server-rust/src/query.rs | 2 +- packages/duckdb-server-rust/src/websocket.rs | 7 +- 6 files changed, 94 insertions(+), 96 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 21794c905..c0f4c987d 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -107,9 +107,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "arrow" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219d05930b81663fd3b32e3bde8ce5bff3c4d23052a99f11a8fa50a3b47b2658" +checksum = "6127ea5e585a12ec9f742232442828ebaf264dfa5eefdd71282376c599562b77" dependencies = [ "arrow-arith", "arrow-array", @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0272150200c07a86a390be651abdd320a2d12e84535f0837566ca87ecd8f95e0" +checksum = "7add7f39210b7d726e2a8efc0083e7bf06e8f2d15bdb4896b564dce4410fbf5d" dependencies = [ "arrow-array", "arrow-buffer", @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8010572cf8c745e242d1b632bd97bd6d4f40fefed5ed1290a8f433abaa686fea" +checksum = "81c16ec702d3898c2f5cfdc148443c6cd7dbe5bac28399859eb0a3d38f072827" dependencies = [ "ahash 0.8.11", "arrow-buffer", @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0a2432f0cba5692bf4cb757469c66791394bac9ec7ce63c1afe74744c37b27" +checksum = "cae6970bab043c4fbc10aee1660ceb5b306d0c42c8cc5f6ae564efcd9759b663" dependencies = [ "bytes", "half", @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9abc10cd7995e83505cc290df9384d6e5412b207b79ce6bdff89a10505ed2cba" +checksum = "1c7ef44f26ef4f8edc392a048324ed5d757ad09135eff6d5509e6450d39e0398" dependencies = [ "arrow-array", "arrow-buffer", @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "arrow-csv" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95cbcba196b862270bf2a5edb75927380a7f3a163622c61d40cbba416a6305f2" +checksum = "5f843490bd258c5182b66e888161bb6f198f49f3792f7c7f98198b924ae0f564" dependencies = [ "arrow-array", "arrow-buffer", @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2742ac1f6650696ab08c88f6dd3f0eb68ce10f8c253958a18c943a68cd04aec5" +checksum = "a769666ffac256dd301006faca1ca553d0ae7cffcf4cd07095f73f95eb226514" dependencies = [ "arrow-buffer", "arrow-schema", @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "arrow-ipc" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42ea853130f7e78b9b9d178cb4cd01dee0f78e64d96c2949dc0a915d6d9e19d" +checksum = "dbf9c3fb57390a1af0b7bb3b5558c1ee1f63905f3eccf49ae7676a8d1e6e5a72" dependencies = [ "arrow-array", "arrow-buffer", @@ -236,9 +236,9 @@ dependencies = [ [[package]] name = "arrow-json" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaafb5714d4e59feae964714d724f880511500e3569cc2a94d02456b403a2a49" +checksum = "654e7f3724176b66ddfacba31af397c48e106fbe4d281c8144e7d237df5acfd7" dependencies = [ "arrow-array", "arrow-buffer", @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e6b61e3dc468f503181dccc2fc705bdcc5f2f146755fa5b56d0a6c5943f412" +checksum = "e8008370e624e8e3c68174faaf793540287106cfda8ad1da862fdc53d8e096b4" dependencies = [ "arrow-array", "arrow-buffer", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848ee52bb92eb459b811fb471175ea3afcf620157674c8794f539838920f9228" +checksum = "ca5e3a6b7fda8d9fe03f3b18a2d946354ea7f3c8e4076dbdb502ad50d9d44824" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -286,18 +286,18 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d9483aaabe910c4781153ae1b6ae0393f72d9ef757d38d09d450070cf2e528" +checksum = "dab1c12b40e29d9f3b699e0203c2a73ba558444c05e388a4377208f8f9c97eee" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "arrow-select" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "849524fa70e0e3c5ab58394c770cb8f514d0122d20de08475f7b472ed8075830" +checksum = "e80159088ffe8c48965cb9b1a7c968b2729f29f37363df7eca177fc3281fe7c3" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "arrow-string" -version = "51.0.0" +version = "52.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9373cb5a021aee58863498c37eb484998ef13377f69989c6c5ccfbd258236cdb" +checksum = "0fd04a6ea7de183648edbcb7a6dd925bbd04c210895f6384c780e27a9b54afcd" dependencies = [ "arrow-array", "arrow-buffer", @@ -342,13 +342,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -551,7 +551,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", "syn_derive", ] @@ -624,9 +624,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.105" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437" +checksum = "907d8581360765417f8f2e0e7d602733bbed60156b4465b7617243689ef9b83d" dependencies = [ "jobserver", "libc", @@ -767,9 +767,9 @@ dependencies = [ [[package]] name = "duckdb" -version = "0.10.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424ede399a5d1084e65c0888fda71e407e5809400c92ff2cf510bfd1697b9c76" +checksum = "626373a331b49f94b24edc4e53a59b0b354f085ac3b339d43d31da7a9b145004" dependencies = [ "arrow", "cast", @@ -779,6 +779,7 @@ dependencies = [ "hashlink", "libduckdb-sys", "memchr", + "num-integer", "rust_decimal", "smallvec", "strum 0.25.0", @@ -853,9 +854,9 @@ dependencies = [ [[package]] name = "flatbuffers" -version = "23.5.26" +version = "24.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" +checksum = "8add37afff2d4ffa83bc748a70b4b1370984f6980768554182424ef71447c35f" dependencies = [ "bitflags 1.3.2", "rustc_version", @@ -948,7 +949,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -1097,9 +1098,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", @@ -1132,9 +1133,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -1310,9 +1311,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libduckdb-sys" -version = "0.10.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b3f02cecc430f61561bde538d42af4be2d9d5a8b058f74883e460bc1055461" +checksum = "fa48143af4679c674db9ad7951ff1d3ce67b8b55578e523d96af54152df6c13b" dependencies = [ "autocfg", "cc", @@ -1580,7 +1581,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -1967,7 +1968,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2111,7 +2112,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2124,7 +2125,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2140,9 +2141,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.69" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -2158,7 +2159,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2192,22 +2193,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2231,9 +2232,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2271,7 +2272,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2395,7 +2396,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] @@ -2514,9 +2515,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "valuable" @@ -2563,7 +2564,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", "wasm-bindgen-shared", ] @@ -2585,7 +2586,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2812,32 +2813,32 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.71", ] [[package]] name = "zstd" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.1.0" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 5516792c2..c12601b03 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -6,25 +6,25 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -duckdb = { version = "0.10", features = ["bundled", "csv", "json", "parquet", "url", "httpfs"] } +anyhow = "1.0" +arrow = "52.1" +async-trait = "0.1.80" axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing"] } axum-server = { version = "0.6", features = ["tls-rustls"] } -tokio = { version = "1", features = ["full"] } -tower-http = { version = "0.5.0", features = ["cors", "compression-full", "trace"] } +axum-server-dual-protocol = "0.6" +duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url"] } +futures = "0.3" listenfd = "1.0.1" +lru = "0.12" +regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -lru = "0.12" -arrow = "51.0" -anyhow = "1.0" +sha2 = "0.10" +tokio = { version = "1", features = ["full"] } +tower-http = { version = "0.5.0", features = ["cors", "compression-full", "trace"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -async-trait = "0.1.80" -regex = "1.5" -sha2 = "0.10" -axum-server-dual-protocol = "0.6" -futures = "0.3" [dev-dependencies] -tower = { version = "0.4", features = ["util"] } http-body-util = "0.1.0" +tower = { version = "0.4", features = ["util"] } diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index cf855e4db..103540243 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -75,7 +75,7 @@ impl IntoResponse for AppError { tracing::error!("Error: {:?}", error); ( StatusCode::INTERNAL_SERVER_ERROR, - format!("Something went wrong: {}", error), + format!("Something went wrong: {error}"), ) .into_response() } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index e624cca1a..4e5097226 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -27,8 +27,6 @@ mod websocket; use db::DuckDbDatabase; use interfaces::{AppError, AppState, QueryParams, QueryResponse}; -use query::handle_query; -use websocket::handle_websocket; async fn handle_get( State(state): State>, @@ -38,11 +36,11 @@ async fn handle_get( if let Some(ws) = ws { // WebSocket upgrade Ok(QueryResponse::Response( - ws.on_upgrade(|socket| handle_websocket(socket, state)), + ws.on_upgrade(|socket| websocket::handle(socket, state)), )) } else { // HTTP request - handle_query(state, params).await + query::handle(state, params).await } } @@ -50,7 +48,7 @@ async fn handle_post( State(state): State>, Json(params): Json, ) -> Result { - handle_query(state, params).await + query::handle(state, params).await } pub fn app() -> Result { @@ -118,7 +116,7 @@ async fn main() -> Result<(), Box> { // Run the server tracing::debug!( - "DuckDB Server listening on https://{}", + "DuckDB Server listening on http(s)://{0} and ws://{0}", listener.local_addr().unwrap() ); axum_server_dual_protocol::from_tcp_dual_protocol(listener, config) diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index 1017fffb0..f70708899 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -6,7 +6,7 @@ use crate::bundle::{create, load}; use crate::cache::retrieve; use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; -pub async fn handle_query( +pub async fn handle( state: Arc, params: QueryParams, ) -> Result { diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 425db4017..676b7bc54 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -1,13 +1,12 @@ use crate::{ interfaces::{AppError, QueryResponse}, - query::handle_query, AppState, }; use axum::extract::ws::{Message, WebSocket}; use serde_json::json; use std::sync::Arc; -pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { +pub async fn handle(mut socket: WebSocket, state: Arc) { while let Some(msg) = socket.recv().await { if let Ok(msg) = msg { match msg { @@ -38,7 +37,7 @@ pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { QueryResponse::Empty => { socket.send(Message::Text("{}".to_string())).await } - _ => { + QueryResponse::Response(_) => { socket .send(Message::Text( json!({"error": "Unknown response Type"}).to_string(), @@ -63,5 +62,5 @@ pub async fn handle_websocket(mut socket: WebSocket, state: Arc) { async fn handle_message(message: String, state: Arc) -> Result { let params = serde_json::from_str(&message)?; - handle_query(state, params).await + crate::query::handle(state, params).await } From 52a8a2a978cf54ca16d6e91c7369f2352727a7f3 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 12 Jul 2024 17:18:37 -0400 Subject: [PATCH 34/66] format --- packages/duckdb-server-rust/src/query.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index f70708899..bb7fc54de 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -6,10 +6,7 @@ use crate::bundle::{create, load}; use crate::cache::retrieve; use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; -pub async fn handle( - state: Arc, - params: QueryParams, -) -> Result { +pub async fn handle(state: Arc, params: QueryParams) -> Result { match ¶ms.query_type { None => Err(AppError::BadRequest), Some(query_command) => { From 0921a27a58a1323d34cae519c6739e4f42ee24b6 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sat, 13 Jul 2024 09:26:17 -0400 Subject: [PATCH 35/66] simplify --- packages/duckdb-server-rust/src/bundle.rs | 9 +- packages/duckdb-server-rust/src/db.rs | 4 +- packages/duckdb-server-rust/src/query.rs | 113 +++++++++++----------- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 4883873ac..9b6a51833 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -74,9 +74,12 @@ pub async fn create( Command::Arrow }; let key = get_key(sql, &command); - let result = retrieve(cache, sql, &command, true, || match command { - Command::Arrow => db.get_arrow_bytes(sql), - _ => db.get_json(sql), + let result = retrieve(cache, sql, &command, true, || { + if let Command::Arrow = command { + db.get_arrow(sql) + } else { + db.get_json(sql) + } }) .await?; fs::write(bundle_dir.join(&key), &result) diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index e2e29e98e..671973af7 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -8,7 +8,7 @@ use tokio::sync::Mutex; pub trait Database: Send + Sync { async fn execute(&self, sql: &str) -> Result<()>; async fn get_json(&self, sql: &str) -> Result>; - async fn get_arrow_bytes(&self, sql: &str) -> Result>; + async fn get_arrow(&self, sql: &str) -> Result>; } pub struct DuckDbDatabase { @@ -46,7 +46,7 @@ impl Database for DuckDbDatabase { Ok(json_data) } - async fn get_arrow_bytes(&self, sql: &str) -> Result> { + async fn get_arrow(&self, sql: &str) -> Result> { let conn = self.con.lock().await; let mut stmt = conn.prepare(sql)?; let arrow = stmt.query_arrow([])?; diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index bb7fc54de..ffe5461bc 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -7,66 +7,61 @@ use crate::cache::retrieve; use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; pub async fn handle(state: Arc, params: QueryParams) -> Result { - match ¶ms.query_type { - None => Err(AppError::BadRequest), - Some(query_command) => { - tracing::info!("Command: '{:?}', Params: '{:?}'", query_command, params); - - match query_command { - Command::Exec => { - if let Some(sql) = params.sql.as_deref() { - state.db.execute(sql).await?; - Ok(QueryResponse::Empty) - } else { - Err(AppError::BadRequest) - } - } - Command::Arrow => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let buffer = retrieve(&state.cache, sql, query_command, persist, || { - state.db.get_arrow_bytes(sql) - }) - .await?; - Ok(QueryResponse::Arrow(buffer)) - } else { - Err(AppError::BadRequest) - } - } - Command::Json => { - if let Some(sql) = params.sql.as_deref() { - let persist = params.persist.unwrap_or(true); - let json: Vec = - retrieve(&state.cache, sql, query_command, persist, || { - state.db.get_json(sql) - }) - .await?; - let string = String::from_utf8(json)?; - Ok(QueryResponse::Json(string)) - } else { - Err(AppError::BadRequest) - } - } - Command::CreateBundle => { - if let Some(queries) = params.queries { - let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; - Ok(QueryResponse::Empty) - } else { - Err(AppError::BadRequest) - } - } - Command::LoadBundle => { - if let Some(bundle_name) = params.name { - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); - load(state.db.as_ref(), &state.cache, &bundle_path).await?; - Ok(QueryResponse::Empty) - } else { - Err(AppError::BadRequest) - } - } + let command = ¶ms.query_type; + tracing::info!("Command: '{:?}', Params: '{:?}'", command, params); + match command { + Some(Command::Exec) => { + if let Some(sql) = params.sql.as_deref() { + state.db.execute(sql).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } + Some(Command::Arrow) => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let buffer = retrieve(&state.cache, sql, &Command::Arrow, persist, || { + state.db.get_arrow(sql) + }) + .await?; + Ok(QueryResponse::Arrow(buffer)) + } else { + Err(AppError::BadRequest) + } + } + Some(Command::Json) => { + if let Some(sql) = params.sql.as_deref() { + let persist = params.persist.unwrap_or(true); + let json: Vec = retrieve(&state.cache, sql, &Command::Json, persist, || { + state.db.get_json(sql) + }) + .await?; + let string = String::from_utf8(json)?; + Ok(QueryResponse::Json(string)) + } else { + Err(AppError::BadRequest) } } + Some(Command::CreateBundle) => { + if let Some(queries) = params.queries { + let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } + Some(Command::LoadBundle) => { + if let Some(bundle_name) = params.name { + let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + load(state.db.as_ref(), &state.cache, &bundle_path).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } + None => Err(AppError::BadRequest), } } From b40b3af217848e060d81d994bb6d3adae37a81cc Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 14 Jul 2024 09:26:40 -0400 Subject: [PATCH 36/66] move arrow up --- packages/duckdb-server-rust/Cargo.lock | 8 ++++---- packages/duckdb-server-rust/src/interfaces.rs | 16 ++++++++-------- packages/duckdb-server-rust/src/query.rs | 16 ++++++++-------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index c0f4c987d..130e90e45 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -612,9 +612,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cast" @@ -624,9 +624,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907d8581360765417f8f2e0e7d602733bbed60156b4465b7617243689ef9b83d" +checksum = "9711f33475c22aab363b05564a17d7b789bf3dfec5ebabb586adee56f0e271b5" dependencies = [ "jobserver", "libc", diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 103540243..e9e8d59f6 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -18,8 +18,8 @@ pub struct AppState { #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "kebab-case")] pub enum Command { - Exec, Arrow, + Exec, Json, CreateBundle, LoadBundle, @@ -36,8 +36,8 @@ pub struct QueryParams { } pub enum QueryResponse { - Json(String), Arrow(Vec), + Json(String), Response(Response), Empty, } @@ -45,18 +45,18 @@ pub enum QueryResponse { impl IntoResponse for QueryResponse { fn into_response(self) -> Response { match self { - QueryResponse::Json(value) => ( - StatusCode::OK, - [("Content-Type", "application/json")], - value, - ) - .into_response(), QueryResponse::Arrow(bytes) => ( StatusCode::OK, [("Content-Type", "application/vnd.apache.arrow.stream")], Bytes::from(bytes), ) .into_response(), + QueryResponse::Json(value) => ( + StatusCode::OK, + [("Content-Type", "application/json")], + value, + ) + .into_response(), QueryResponse::Response(response) => response, QueryResponse::Empty => StatusCode::OK.into_response(), } diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index ffe5461bc..eace36f38 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -10,14 +10,6 @@ pub async fn handle(state: Arc, params: QueryParams) -> Result { - if let Some(sql) = params.sql.as_deref() { - state.db.execute(sql).await?; - Ok(QueryResponse::Empty) - } else { - Err(AppError::BadRequest) - } - } Some(Command::Arrow) => { if let Some(sql) = params.sql.as_deref() { let persist = params.persist.unwrap_or(true); @@ -30,6 +22,14 @@ pub async fn handle(state: Arc, params: QueryParams) -> Result { + if let Some(sql) = params.sql.as_deref() { + state.db.execute(sql).await?; + Ok(QueryResponse::Empty) + } else { + Err(AppError::BadRequest) + } + } Some(Command::Json) => { if let Some(sql) = params.sql.as_deref() { let persist = params.persist.unwrap_or(true); From b3af2866294ee28a02242a6775170badb8dd53ae Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 14 Jul 2024 09:42:30 -0400 Subject: [PATCH 37/66] avoid clone in state --- packages/duckdb-server-rust/src/main.rs | 4 ++-- packages/duckdb-server-rust/src/query.rs | 3 +-- packages/duckdb-server-rust/src/websocket.rs | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 4e5097226..12a3763ea 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -40,7 +40,7 @@ async fn handle_get( )) } else { // HTTP request - query::handle(state, params).await + query::handle(&state, params).await } } @@ -48,7 +48,7 @@ async fn handle_post( State(state): State>, Json(params): Json, ) -> Result { - query::handle(state, params).await + query::handle(&state, params).await } pub fn app() -> Result { diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index eace36f38..dd7964e98 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -1,12 +1,11 @@ use anyhow::Result; use std::path::Path; -use std::sync::Arc; use crate::bundle::{create, load}; use crate::cache::retrieve; use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; -pub async fn handle(state: Arc, params: QueryParams) -> Result { +pub async fn handle(state: &AppState, params: QueryParams) -> Result { let command = ¶ms.query_type; tracing::info!("Command: '{:?}', Params: '{:?}'", command, params); match command { diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 676b7bc54..79625f4f0 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -11,7 +11,7 @@ pub async fn handle(mut socket: WebSocket, state: Arc) { if let Ok(msg) = msg { match msg { Message::Text(text) => { - let response = handle_message(text, state.clone()).await; + let response = handle_message(text, &state).await; if match response { Err(error) => match error { AppError::BadRequest => { @@ -60,7 +60,7 @@ pub async fn handle(mut socket: WebSocket, state: Arc) { } } -async fn handle_message(message: String, state: Arc) -> Result { +async fn handle_message(message: String, state: &AppState) -> Result { let params = serde_json::from_str(&message)?; - crate::query::handle(state, params).await + crate::query::handle(&state, params).await } From a042ebfbb37582cd6ecb02bcddf2247b40ecda71 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 14 Jul 2024 09:47:29 -0400 Subject: [PATCH 38/66] avoid another arc --- packages/duckdb-server-rust/src/interfaces.rs | 3 +-- packages/duckdb-server-rust/src/main.rs | 2 +- packages/duckdb-server-rust/src/websocket.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index e9e8d59f6..94fb44894 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -4,14 +4,13 @@ use axum::{ response::{IntoResponse, Response}, }; use serde::{Deserialize, Serialize}; -use std::sync::Arc; use tokio::sync::Mutex; use crate::bundle::Query as BundleQuery; use crate::db::Database; pub struct AppState { - pub db: Arc, + pub db: Box, pub cache: Mutex>>, } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 12a3763ea..6925b945a 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -54,7 +54,7 @@ async fn handle_post( pub fn app() -> Result { // Database and state setup let con = Connection::open_in_memory()?; - let db = Arc::new(DuckDbDatabase::new(con)); + let db = Box::new(DuckDbDatabase::new(con)); let cache = lru::LruCache::new(1000.try_into()?); let state = Arc::new(AppState { diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 79625f4f0..ac0bcc008 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -62,5 +62,5 @@ pub async fn handle(mut socket: WebSocket, state: Arc) { async fn handle_message(message: String, state: &AppState) -> Result { let params = serde_json::from_str(&message)?; - crate::query::handle(&state, params).await + crate::query::handle(state, params).await } From 3b1cd5c04409a8002db6111ad00ff04f3e21de0d Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 14 Jul 2024 10:08:31 -0400 Subject: [PATCH 39/66] Use a connection pool rather than a lock on the connection --- packages/duckdb-server-rust/Cargo.lock | 22 ++++++++++++++++++ packages/duckdb-server-rust/Cargo.toml | 3 ++- packages/duckdb-server-rust/src/db.rs | 30 +++++++++++++------------ packages/duckdb-server-rust/src/main.rs | 8 +++---- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 130e90e45..62ed1d85c 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -780,6 +780,7 @@ dependencies = [ "libduckdb-sys", "memchr", "num-integer", + "r2d2", "rust_decimal", "smallvec", "strum 0.25.0", @@ -801,6 +802,7 @@ dependencies = [ "http-body-util", "listenfd", "lru", + "r2d2", "regex", "serde", "serde_json", @@ -1678,6 +1680,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + [[package]] name = "radium" version = "0.7.0" @@ -1923,6 +1936,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.2.0" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index c12601b03..c6002861a 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -12,10 +12,11 @@ async-trait = "0.1.80" axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing"] } axum-server = { version = "0.6", features = ["tls-rustls"] } axum-server-dual-protocol = "0.6" -duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url"] } +duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url", "r2d2"] } futures = "0.3" listenfd = "1.0.1" lru = "0.12" +r2d2 = "0.8" regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index 671973af7..c3b7f78d0 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,8 +1,6 @@ use anyhow::Result; use async_trait::async_trait; -use duckdb::Connection; -use std::sync::Arc; -use tokio::sync::Mutex; +use duckdb::DuckdbConnectionManager; #[async_trait] pub trait Database: Send + Sync { @@ -11,28 +9,32 @@ pub trait Database: Send + Sync { async fn get_arrow(&self, sql: &str) -> Result>; } -pub struct DuckDbDatabase { - con: Arc>, +pub struct ConnectionPool { + pool: r2d2::Pool, } -impl DuckDbDatabase { - pub fn new(con: Connection) -> Self { - Self { - con: Arc::new(Mutex::new(con)), - } +impl ConnectionPool { + pub fn new(db_path: &str, pool_size: u32) -> Result { + let manager = DuckdbConnectionManager::file(db_path)?; + let pool = r2d2::Pool::builder().max_size(pool_size).build(manager)?; + Ok(Self { pool }) + } + + pub fn get(&self) -> Result> { + Ok(self.pool.get()?) } } #[async_trait] -impl Database for DuckDbDatabase { +impl Database for ConnectionPool { async fn execute(&self, sql: &str) -> Result<()> { - let conn = self.con.lock().await; + let conn = self.get()?; conn.execute_batch(sql)?; Ok(()) } async fn get_json(&self, sql: &str) -> Result> { - let conn = self.con.lock().await; + let conn = self.get()?; let mut stmt = conn.prepare(sql)?; let arrow = stmt.query_arrow([])?; @@ -47,7 +49,7 @@ impl Database for DuckDbDatabase { } async fn get_arrow(&self, sql: &str) -> Result> { - let conn = self.con.lock().await; + let conn = self.get()?; let mut stmt = conn.prepare(sql)?; let arrow = stmt.query_arrow([])?; let schema = arrow.get_schema(); diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 6925b945a..fbde2f823 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -7,7 +7,6 @@ use axum::{ Router, }; use axum_server::tls_rustls::RustlsConfig; -use duckdb::Connection; use listenfd::ListenFd; use std::net::TcpListener; use std::sync::Arc; @@ -25,7 +24,7 @@ mod interfaces; mod query; mod websocket; -use db::DuckDbDatabase; +use db::ConnectionPool; use interfaces::{AppError, AppState, QueryParams, QueryResponse}; async fn handle_get( @@ -53,12 +52,11 @@ async fn handle_post( pub fn app() -> Result { // Database and state setup - let con = Connection::open_in_memory()?; - let db = Box::new(DuckDbDatabase::new(con)); + let db = ConnectionPool::new(":memory:", 10)?; let cache = lru::LruCache::new(1000.try_into()?); let state = Arc::new(AppState { - db, + db: Box::new(db), cache: Mutex::new(cache), }); From 3583ec5d28887258b8898a74b261857027bad1f3 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 15 Jul 2024 17:31:41 -0400 Subject: [PATCH 40/66] streaming arrow --- packages/duckdb-server-rust/Cargo.lock | 102 +++++++++ packages/duckdb-server-rust/Cargo.toml | 4 + packages/duckdb-server-rust/src/bundle.rs | 22 +- packages/duckdb-server-rust/src/cache.rs | 8 +- packages/duckdb-server-rust/src/db.rs | 197 ++++++++++++++---- packages/duckdb-server-rust/src/interfaces.rs | 67 +++++- packages/duckdb-server-rust/src/query.rs | 10 +- 7 files changed, 345 insertions(+), 65 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 62ed1d85c..759d5a97e 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -340,6 +340,28 @@ dependencies = [ "zstd-safe", ] +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "async-trait" version = "0.1.81" @@ -471,6 +493,25 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-streams" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2eb21ea12eb351da044b8d9ea9d1f622c7f05e9a4ad0a441ed253026b4b4cd" +dependencies = [ + "arrow", + "axum", + "bytes", + "cargo-husky", + "futures", + "http", + "http-body", + "mime", + "tokio", + "tokio-stream", + "tokio-util", +] + [[package]] name = "backtrace" version = "0.3.73" @@ -616,6 +657,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +[[package]] +name = "cargo-husky" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" + [[package]] name = "cast" version = "0.3.0" @@ -755,6 +802,46 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "deadpool" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6541a3916932fe57768d4be0b1ffb5ec7cbf74ca8c903fdfd5c0fe8aa958f0ed" +dependencies = [ + "deadpool-runtime", + "num_cpus", + "tokio", +] + +[[package]] +name = "deadpool-r2d2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8976b03b05529a3ea46dba37aaa51e6990bf85a075f8d8e1b150d50d816f71a" +dependencies = [ + "deadpool", + "deadpool-sync", + "r2d2", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" +dependencies = [ + "tokio", +] + +[[package]] +name = "deadpool-sync" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524bc3df0d57e98ecd022e21ba31166c2625e7d3e5bcc4510efaeeab4abcab04" +dependencies = [ + "deadpool-runtime", +] + [[package]] name = "digest" version = "0.10.7" @@ -793,10 +880,14 @@ version = "0.1.0" dependencies = [ "anyhow", "arrow", + "async-stream", "async-trait", "axum", "axum-server", "axum-server-dual-protocol", + "axum-streams", + "deadpool", + "deadpool-r2d2", "duckdb", "futures", "http-body-util", @@ -2307,6 +2398,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.21.0" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index c6002861a..ce0a7b6c1 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -25,6 +25,10 @@ tokio = { version = "1", features = ["full"] } tower-http = { version = "0.5.0", features = ["cors", "compression-full", "trace"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } +axum-streams = { version = "0.18", features=["arrow"] } +async-stream = "0.3" +deadpool = { version = "0.12", features = ["managed"] } +deadpool-r2d2 = {version = "0.4.1"} [dev-dependencies] http-body-util = "0.1.0" diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 9b6a51833..a5fe9fe0b 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -39,11 +39,11 @@ pub async fn create( fs::create_dir_all(bundle_dir).context("Failed to create bundle directory")?; for query in queries { - let sql = &query.sql; + let sql = query.sql; if let Some(alias) = &query.alias { let file = bundle_dir.join(format!("{alias}.parquet")); - db.execute(&format!( + db.execute(format!( "COPY ({}) TO '{}' (FORMAT PARQUET)", sql, file.display() @@ -51,15 +51,15 @@ pub async fn create( .await?; manifest.tables.push(alias.clone()); } else if sql.starts_with("CREATE ") { - if view_re.is_match(sql) { + if view_re.is_match(&sql) { continue; // Ignore views } - if let Some(captures) = table_re.captures(sql) { + if let Some(captures) = table_re.captures(&sql) { let table = captures.get(3).unwrap().as_str(); let file = bundle_dir.join(format!("{table}.parquet")); - db.execute(sql).await?; - db.execute(&format!( + db.execute(sql.clone()).await?; + db.execute(format!( "COPY {} TO '{}' (FORMAT PARQUET)", table, file.display() @@ -67,14 +67,14 @@ pub async fn create( .await?; manifest.tables.push(table.to_string()); } - } else if !pragma_re.is_match(sql) { - let command = if describe_re.is_match(sql) { + } else if !pragma_re.is_match(&sql) { + let command = if describe_re.is_match(&sql) { Command::Json } else { Command::Arrow }; - let key = get_key(sql, &command); - let result = retrieve(cache, sql, &command, true, || { + let key = get_key(&sql, &command); + let result = retrieve(cache, sql, &command, true, |sql| { if let Command::Arrow = command { db.get_arrow(sql) } else { @@ -120,7 +120,7 @@ pub async fn load( // Load precomputed temp tables into the database for table in &manifest.tables { let file = bundle_dir.join(format!("{table}.parquet")); - db.execute(&format!( + db.execute(format!( "CREATE TEMP TABLE IF NOT EXISTS {} AS SELECT * FROM '{}'", table, file.display() diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index 15a8f9c0d..631481e3f 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -13,23 +13,23 @@ pub fn get_key(sql: &str, command: &Command) -> String { pub async fn retrieve( cache: &Mutex>>, - sql: &str, + sql: String, command: &Command, persist: bool, f: F, ) -> Result> where - F: FnOnce() -> Fut, + F: FnOnce(String) -> Fut, Fut: std::future::Future>>, { - let key = get_key(sql, command); + let key = get_key(&sql, command); if let Some(cached) = cache.lock().await.get(&key) { tracing::debug!("Cache hit {}!", key); return Ok(cached.clone()); } - let result = f().await?; + let result = f(sql).await?; if persist { cache.lock().await.put(key, result.clone()); diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index c3b7f78d0..2f8f77c65 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,71 +1,186 @@ -use anyhow::Result; +use anyhow::{Error, Result}; +use arrow::record_batch::RecordBatch; +use async_stream::try_stream; +use async_stream::stream; use async_trait::async_trait; +use axum::response::IntoResponse; +use axum_streams::StreamBodyAs; +use deadpool::managed::{Manager, Object, Pool}; +use deadpool_r2d2::Runtime; +use duckdb::arrow::ipc::writer::StreamWriter; use duckdb::DuckdbConnectionManager; +use futures::prelude::*; +use futures::stream::BoxStream; +use futures::stream::Stream; +use std::{pin::Pin, sync::Arc}; +use tracing::span::Record; +use futures::future::FutureExt; +use futures::stream::StreamExt; + +use crate::interfaces::adapt_anyhow_error; #[async_trait] pub trait Database: Send + Sync { - async fn execute(&self, sql: &str) -> Result<()>; - async fn get_json(&self, sql: &str) -> Result>; - async fn get_arrow(&self, sql: &str) -> Result>; + async fn execute(&self, sql: String) -> Result<()>; + async fn get_json(&self, sql: String) -> Result>; + async fn get_arrow(&self, sql: String) -> Result>; + // async fn stream_arrow(&self, sql: String) -> Result; + async fn stream_record_batch( + &self, + sql: String, + ) -> impl Stream;// Result>>; } +type DuckDBManager = deadpool_r2d2::Manager; +type DuckDBPool = deadpool_r2d2::Pool; + pub struct ConnectionPool { - pool: r2d2::Pool, + pool: DuckDBPool, } impl ConnectionPool { - pub fn new(db_path: &str, pool_size: u32) -> Result { - let manager = DuckdbConnectionManager::file(db_path)?; - let pool = r2d2::Pool::builder().max_size(pool_size).build(manager)?; + pub fn new(db_path: &str, pool_size: usize) -> Result { + let r2d2_manager = DuckdbConnectionManager::file(db_path)?; + let manager: deadpool_r2d2::Manager = + DuckDBManager::new(r2d2_manager, Runtime::Tokio1); + let pool = DuckDBPool::builder(manager).max_size(pool_size).build()?; Ok(Self { pool }) } - - pub fn get(&self) -> Result> { - Ok(self.pool.get()?) - } } #[async_trait] impl Database for ConnectionPool { - async fn execute(&self, sql: &str) -> Result<()> { - let conn = self.get()?; - conn.execute_batch(sql)?; + async fn execute(&self, sql: String) -> Result<()> { + let manager = self.pool.get().await?; + manager.interact(move |conn| conn.execute_batch(&sql)) + .await + .map_err(adapt_anyhow_error)?; Ok(()) } - async fn get_json(&self, sql: &str) -> Result> { - let conn = self.get()?; - let mut stmt = conn.prepare(sql)?; - let arrow = stmt.query_arrow([])?; - - let buf = Vec::new(); - let mut writer = arrow::json::ArrayWriter::new(buf); - for batch in arrow { - writer.write(&batch)?; - } - writer.finish()?; - let json_data = writer.into_inner(); + async fn get_json(&self, sql: String) -> Result> { + let manager = self.pool.get().await?; + let json_data = manager + .interact(move |conn| { + let mut stmt = conn.prepare(&sql)?; + let arrow = stmt.query_arrow([])?; + + let buf = Vec::new(); + let mut writer = arrow::json::ArrayWriter::new(buf); + for batch in arrow { + writer.write(&batch)?; + } + writer.finish()?; + Ok::, Error>(writer.into_inner()) + }) + .await + .map_err(adapt_anyhow_error)??; + Ok(json_data) } - async fn get_arrow(&self, sql: &str) -> Result> { - let conn = self.get()?; - let mut stmt = conn.prepare(sql)?; - let arrow = stmt.query_arrow([])?; - let schema = arrow.get_schema(); + async fn get_arrow(&self, sql: String) -> Result> { + let manager = self.pool.get().await?; + let buffer = manager + .interact(move |conn| { + let mut stmt = conn.prepare(&sql)?; + let arrow = stmt.query_arrow([])?; + let schema = arrow.get_schema(); + + let mut buffer: Vec = Vec::new(); + { + let schema_ref = schema.as_ref(); + let mut writer = + arrow::ipc::writer::FileWriter::try_new(&mut buffer, schema_ref)?; - let mut buffer: Vec = Vec::new(); - { - let schema_ref = schema.as_ref(); - let mut writer = arrow::ipc::writer::FileWriter::try_new(&mut buffer, schema_ref)?; + for batch in arrow { + writer.write(&batch)?; + } - for batch in arrow { - writer.write(&batch)?; - } + writer.finish()?; + } - writer.finish()?; - } + Ok::, Error>(buffer) + }) + .await + .map_err(adapt_anyhow_error)??; Ok(buffer) } + + // async fn stream_arrow(&self, sql: String) -> Result { + // let conn = self.pool.get().await?; + // let stream = conn.interact(move |client| { + // let mut stmt = client.prepare(&sql)?; + // let arrow = stmt.query_arrow([])?; + // let schema = arrow.get_schema(); + + // let stream = async_stream::try_stream! { + // for batch in arrow { + // yield batch; + // } + // }; + // Ok(StreamBodyAs::arrow_ipc_with_errors(schema, stream)) + // }).await.map_err(adapt_anyhow_error)??; + + // let response = stream.into_response(); + // Ok(response) + // } + + async fn stream_record_batch( + &self, + sql: String, + ) -> Result>> { + let conn = self.pool.get().await?; + + let stream = std::pin::pin! { conn + .interact(move |conn| { + let mut stmt = conn.prepare(&sql)?; + let arrow = stmt.query_arrow([])?; + let schema = arrow.get_schema(); + + let stream = stream! { + for batch in arrow { + yield batch; + } + }; + + Ok(stream) + }) + .await + .map_err(adapt_anyhow_error)?? }; + + Ok(stream) + } + + // fn stream_record_batch(&self, sql: &str) -> impl Stream> { + // let pool = self.pool.clone(); + // async_stream::try_stream! { + // let conn = pool.get()?; + // let mut stmt = conn.prepare(sql)?; + // let arrow = stmt.query_arrow([])?; + + // for batch in arrow { + // yield batch; + // } + // } + // } + + // fn stream_record_batch( + // &self, + // sql: &str, + // ) -> Pin> + Send>> { + // let pool = self.pool.clone(); + // Box::pin(futures::stream::unfold( + // (pool, sql.to_string()), + // |(pool, sql)| async move { + // let conn = pool.get().ok()?; + // let mut stmt = conn.prepare(&sql).ok()?; + // let mut arrow = stmt.query_arrow([]).ok()?; + + // let batch = arrow.next()?; + // Some((Ok(batch), (pool, sql))) + // }, + // )) + // } } diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 94fb44894..cf5b53e09 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -1,9 +1,13 @@ +use anyhow::anyhow; +use axum::Json; use axum::{ body::Bytes, http::StatusCode, response::{IntoResponse, Response}, }; +use deadpool_r2d2::InteractError; use serde::{Deserialize, Serialize}; +use serde_json::json; use tokio::sync::Mutex; use crate::bundle::Query as BundleQuery; @@ -69,17 +73,17 @@ pub enum AppError { impl IntoResponse for AppError { fn into_response(self) -> Response { - match self { + let (status, err_msg) = match self { AppError::Error(error) => { tracing::error!("Error: {:?}", error); ( StatusCode::INTERNAL_SERVER_ERROR, format!("Something went wrong: {error}"), ) - .into_response() } - AppError::BadRequest => (StatusCode::BAD_REQUEST).into_response(), - } + AppError::BadRequest => (StatusCode::BAD_REQUEST, "Bad request".to_string()), + }; + (status, Json(json!({ "message": err_msg }))).into_response() } } @@ -91,3 +95,58 @@ where AppError::Error(err.into()) } } + +pub fn adapt_anyhow_error(error: T) -> anyhow::Error { + error.as_anyhow_error() +} + +pub trait Error { + fn as_anyhow_error(&self) -> anyhow::Error; +} + +impl Error for InteractError { + fn as_anyhow_error(&self) -> anyhow::Error { + anyhow!("Interact Error {:?}", self) + } +} + + +// pub fn adapt_app_error(error: T) -> AppError { +// error.as_app_error() +// } + +// pub trait Error { +// fn as_app_error(&self) -> AppError; +// } + +// impl Error for InteractError { +// fn as_app_error(&self) -> AppError { +// AppError::InteractError +// } +// } + +// #[derive(Debug)] +// pub struct InfraError; + +// pub fn adapt_infra_error(error: T) -> InfraError { +// error.as_infra_error() +// } + +// pub trait Error { +// fn as_infra_error(&self) -> InfraError; +// } + +// impl Error for InteractError { +// fn as_infra_error(&self) -> InfraError { +// InfraError +// } +// } + +// impl From for InfraError +// where +// E: Into, +// { +// fn from(_: E) -> Self { +// InfraError +// } +// } diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index dd7964e98..c4148c712 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -10,9 +10,9 @@ pub async fn handle(state: &AppState, params: QueryParams) -> Result { - if let Some(sql) = params.sql.as_deref() { + if let Some(sql) = params.sql { let persist = params.persist.unwrap_or(true); - let buffer = retrieve(&state.cache, sql, &Command::Arrow, persist, || { + let buffer = retrieve(&state.cache, sql, &Command::Arrow, persist, |sql| { state.db.get_arrow(sql) }) .await?; @@ -22,7 +22,7 @@ pub async fn handle(state: &AppState, params: QueryParams) -> Result { - if let Some(sql) = params.sql.as_deref() { + if let Some(sql) = params.sql { state.db.execute(sql).await?; Ok(QueryResponse::Empty) } else { @@ -30,9 +30,9 @@ pub async fn handle(state: &AppState, params: QueryParams) -> Result { - if let Some(sql) = params.sql.as_deref() { + if let Some(sql) = params.sql { let persist = params.persist.unwrap_or(true); - let json: Vec = retrieve(&state.cache, sql, &Command::Json, persist, || { + let json: Vec = retrieve(&state.cache, sql, &Command::Json, persist, |sql| { state.db.get_json(sql) }) .await?; From e22544a35d5def8f16c2d3fc273b977449069a26 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 15 Jul 2024 17:33:31 -0400 Subject: [PATCH 41/66] debug handler --- packages/duckdb-server-rust/Cargo.lock | 13 +++++++++++++ packages/duckdb-server-rust/Cargo.toml | 2 +- packages/duckdb-server-rust/src/main.rs | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 62ed1d85c..c3b3abe20 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -380,6 +380,7 @@ checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", + "axum-macros", "base64 0.21.7", "bytes", "futures-util", @@ -430,6 +431,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "axum-server" version = "0.6.0" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index c6002861a..2038fe3d2 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" anyhow = "1.0" arrow = "52.1" async-trait = "0.1.80" -axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing"] } +axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing", "macros"] } axum-server = { version = "0.6", features = ["tls-rustls"] } axum-server-dual-protocol = "0.6" duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url", "r2d2"] } diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index fbde2f823..c0822155e 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -5,6 +5,7 @@ use axum::{ response::Json, routing::get, Router, + debug_handler }; use axum_server::tls_rustls::RustlsConfig; use listenfd::ListenFd; @@ -27,6 +28,7 @@ mod websocket; use db::ConnectionPool; use interfaces::{AppError, AppState, QueryParams, QueryResponse}; +#[debug_handler] async fn handle_get( State(state): State>, ws: Option, @@ -43,6 +45,7 @@ async fn handle_get( } } +#[debug_handler] async fn handle_post( State(state): State>, Json(params): Json, From 322c219cc689d74c366901445da6fa7257a02ebf Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 18 Jul 2024 10:19:42 -0400 Subject: [PATCH 42/66] style --- packages/duckdb-server-rust/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index c0822155e..747380772 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,11 +1,11 @@ use anyhow::Result; use axum::{ + debug_handler, extract::{Query, State, WebSocketUpgrade}, http::Method, response::Json, routing::get, Router, - debug_handler }; use axum_server::tls_rustls::RustlsConfig; use listenfd::ListenFd; From 277b239f445ba59595261b7b50c65d36631e415c Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 10:41:12 -0400 Subject: [PATCH 43/66] rename server and add more docs --- packages/duckdb-server-rust/Cargo.lock | 63 ++++++++++++------------- packages/duckdb-server-rust/Cargo.toml | 5 +- packages/duckdb-server-rust/Readme.md | 48 ++++++++++++++++++- packages/duckdb-server-rust/src/main.rs | 2 +- 4 files changed, 82 insertions(+), 36 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index c3b3abe20..560a96ee5 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -326,9 +326,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" dependencies = [ "brotli", "flate2", @@ -348,7 +348,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -440,7 +440,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -564,7 +564,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "syn_derive", ] @@ -637,13 +637,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.4" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9711f33475c22aab363b05564a17d7b789bf3dfec5ebabb586adee56f0e271b5" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", - "once_cell", ] [[package]] @@ -801,7 +800,7 @@ dependencies = [ ] [[package]] -name = "duckdb-server-rust" +name = "duckdb-server" version = "0.1.0" dependencies = [ "anyhow", @@ -964,7 +963,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -1568,7 +1567,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall 0.5.3", "smallvec", "windows-targets 0.52.6", ] @@ -1596,7 +1595,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -1751,9 +1750,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags 2.6.0", ] @@ -2003,7 +2002,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2147,7 +2146,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2160,7 +2159,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2176,9 +2175,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -2194,7 +2193,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2228,22 +2227,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2282,9 +2281,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -2307,7 +2306,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2431,7 +2430,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2599,7 +2598,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -2621,7 +2620,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2848,7 +2847,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 2038fe3d2..34cfdae4b 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -1,7 +1,10 @@ [package] -name = "duckdb-server-rust" +name = "duckdb-server" version = "0.1.0" edition = "2021" +repository = "https://github.com/uwdata/mosaic" +description = "DuckDB Server for Mosaic." +license = "BSD 3-Clause" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index db533264e..7b53ee841 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -1,6 +1,38 @@ # DuckDB Server -## Build +A Rust-based server that runs a local DuckDB instance and support queries over Web Sockets or HTTP/HTTPS, returning data in either [Apache Arrow](https://arrow.apache.org/) or JSON format. + +_Note:_ This package provides a local DuckDB server. To instead use DuckDB-WASM in the browser, use the `wasmConnector` in the [`mosaic-core`](https://github.com/uwdata/mosaic/tree/main/packages/mosaic-core) package. + +## Usage + +Install the server with Cargo. + +```sh +cargo install duckdb-server +``` + +Then run the serve with + +```sh +duckdb-server +``` + +You can disable or customize logging with the `RUST_LOG` environment variable. + +```sh +env RUST_LOG="" duckdb-server +``` + +The server can reuse existing sockets with `listenfd`. + +```sh +systemfd --no-pid -s http::3000 -- duckdb-server +``` + +## Developers + +### Build Build the release binary with @@ -8,7 +40,7 @@ Build the release binary with cargo build --release ``` -## Develop +### Develop To run the server and restart it when the code changes, install `cargo-watch` and `systemfd` with @@ -33,3 +65,15 @@ Create certificates for HTTPS with ```sh mkcert localhost ``` + +Before sending a pull request, run the tests with + +```sh +cargo test +cargo clippy +cargo fmt +``` + +### Update dependencies + +Update the lockfile with `cargo update` and look for outdated dependencies with [cargo-outdated](https://github.com/kbknapp/cargo-outdated) `cargo outdated -d 1`. diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 747380772..f81d88d26 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -85,7 +85,7 @@ async fn main() -> Result<(), Box> { tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| { - "duckdb_server_rust=debug,tower_http=debug,axum::rejection=trace".into() + "duckdb_server=debug,tower_http=debug,axum::rejection=trace".into() }), ) .with(tracing_subscriber::fmt::layer()) From e18bbe5b1e904ad45a1655d387af32cef007f850 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 13:51:03 -0400 Subject: [PATCH 44/66] minor refactoring --- packages/duckdb-server-rust/src/main.rs | 5 +---- packages/duckdb-server-rust/src/query.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index f81d88d26..68ce4cd45 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,6 +1,5 @@ use anyhow::Result; use axum::{ - debug_handler, extract::{Query, State, WebSocketUpgrade}, http::Method, response::Json, @@ -28,7 +27,6 @@ mod websocket; use db::ConnectionPool; use interfaces::{AppError, AppState, QueryParams, QueryResponse}; -#[debug_handler] async fn handle_get( State(state): State>, ws: Option, @@ -45,7 +43,6 @@ async fn handle_get( } } -#[debug_handler] async fn handle_post( State(state): State>, Json(params): Json, @@ -116,7 +113,7 @@ async fn main() -> Result<(), Box> { }; // Run the server - tracing::debug!( + tracing::info!( "DuckDB Server listening on http(s)://{0} and ws://{0}", listener.local_addr().unwrap() ); diff --git a/packages/duckdb-server-rust/src/query.rs b/packages/duckdb-server-rust/src/query.rs index dd7964e98..092dae92a 100644 --- a/packages/duckdb-server-rust/src/query.rs +++ b/packages/duckdb-server-rust/src/query.rs @@ -1,10 +1,14 @@ use anyhow::Result; -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::bundle::{create, load}; use crate::cache::retrieve; use crate::interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; +fn create_bundle_path(bundle_name: &str) -> PathBuf { + Path::new(".mosaic").join("bundle").join(bundle_name) +} + pub async fn handle(state: &AppState, params: QueryParams) -> Result { let command = ¶ms.query_type; tracing::info!("Command: '{:?}', Params: '{:?}'", command, params); @@ -45,7 +49,7 @@ pub async fn handle(state: &AppState, params: QueryParams) -> Result { if let Some(queries) = params.queries { let bundle_name = params.name.unwrap_or_else(|| "default".to_string()); - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + let bundle_path = create_bundle_path(&bundle_name); create(state.db.as_ref(), &state.cache, queries, &bundle_path).await?; Ok(QueryResponse::Empty) } else { @@ -54,7 +58,7 @@ pub async fn handle(state: &AppState, params: QueryParams) -> Result { if let Some(bundle_name) = params.name { - let bundle_path = Path::new(".mosaic").join("bundle").join(&bundle_name); + let bundle_path = create_bundle_path(&bundle_name); load(state.db.as_ref(), &state.cache, &bundle_path).await?; Ok(QueryResponse::Empty) } else { From a33d43be8bf19e59e56c465bed4f1a72884b366a Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:11:51 -0400 Subject: [PATCH 45/66] test arrow response --- packages/duckdb-server-rust/src/test.rs | 70 +++++++++++++++++++------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index 6d5bb43b4..f5471bbef 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -1,4 +1,9 @@ use super::*; +use arrow::{ + array::{Int32Array, RecordBatch}, + datatypes::{DataType, Field, Schema}, + ipc::reader::FileReader, +}; use axum::{ body::Body, http::{self, Request, StatusCode}, @@ -8,28 +13,28 @@ use serde_json::json; use tower::ServiceExt; #[tokio::test] -async fn select_1_get() { - let app = app().unwrap(); +async fn select_1_get() -> Result<()> { + let app = app()?; let response = app .oneshot( Request::builder() .uri("/?type=json&sql=SELECT%201%20as%20foo") - .body(Body::empty()) - .unwrap(), + .body(Body::empty())?, ) - .await - .unwrap(); + .await?; assert_eq!(response.status(), StatusCode::OK); - let body = response.into_body().collect().await.unwrap().to_bytes(); + let body = response.into_body().collect().await?.to_bytes(); assert_eq!(&body[..], b"[{\"foo\":1}]"); + + Ok(()) } #[tokio::test] -async fn select_1_post() { - let app = app().unwrap(); +async fn select_1_post() -> Result<()> { + let app = app()?; let response = app .oneshot( @@ -37,16 +42,49 @@ async fn select_1_post() { .method(http::Method::POST) .uri("/") .header(http::header::CONTENT_TYPE, "application/json") - .body(Body::from( - serde_json::to_vec(&json!({"type": "json", "sql": "select 1 as foo"})).unwrap(), - )) - .unwrap(), + .body(Body::from(serde_json::to_vec( + &json!({"type": "json", "sql": "select 1 as foo"}), + )?))?, ) - .await - .unwrap(); + .await?; assert_eq!(response.status(), StatusCode::OK); - let body = response.into_body().collect().await.unwrap().to_bytes(); + let body = response.into_body().collect().await?.to_bytes(); assert_eq!(&body[..], b"[{\"foo\":1}]"); + + Ok(()) +} + +#[tokio::test] +async fn query_arrow() -> Result<()> { + let app = app()?; + + let response = app + .oneshot( + Request::builder() + .method(http::Method::POST) + .uri("/") + .header(http::header::CONTENT_TYPE, "application/json") + .body(Body::from(serde_json::to_vec( + &json!({"type": "arrow", "sql": "select 1 as foo"}), + )?))?, + ) + .await?; + + assert_eq!(response.status(), StatusCode::OK); + + let body = response.into_body().collect().await?; + + let mut reader = FileReader::try_new(std::io::Cursor::new(body.to_bytes()), None)?; + let actual_batch = reader.next().unwrap(); + let actual_batch = actual_batch?; + + let schema = Arc::new(Schema::new(vec![Field::new("foo", DataType::Int32, true)])); + let foo_values = Int32Array::from(vec![1]); + let batch = RecordBatch::try_new(schema.clone(), vec![Arc::new(foo_values)])?; + + assert_eq!(actual_batch, batch); + + Ok(()) } From 40a0c4c4c2d4e0846067521a0bdb75e1d4bdc521 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:12:53 -0400 Subject: [PATCH 46/66] add badge --- packages/duckdb-server-rust/Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 7b53ee841..726f1be83 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -1,5 +1,7 @@ # DuckDB Server +[![Crates.io](https://img.shields.io/crates/v/duckdb-server.svg)](https://crates.io/crates/duckdb-server) + A Rust-based server that runs a local DuckDB instance and support queries over Web Sockets or HTTP/HTTPS, returning data in either [Apache Arrow](https://arrow.apache.org/) or JSON format. _Note:_ This package provides a local DuckDB server. To instead use DuckDB-WASM in the browser, use the `wasmConnector` in the [`mosaic-core`](https://github.com/uwdata/mosaic/tree/main/packages/mosaic-core) package. From 3342f6084fc654e6b246f9c3ffb0f0e6dfbc504e Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:21:28 -0400 Subject: [PATCH 47/66] Release instructions --- packages/duckdb-server-rust/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 726f1be83..2c1ad0346 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -78,4 +78,4 @@ cargo fmt ### Update dependencies -Update the lockfile with `cargo update` and look for outdated dependencies with [cargo-outdated](https://github.com/kbknapp/cargo-outdated) `cargo outdated -d 1`. +Bump the version in `Cargo.toml` and then run `cargo publish`. From 9318522b0f4ac855490bf95c6a734d795f00c63a Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:23:18 -0400 Subject: [PATCH 48/66] update installation instructions --- packages/duckdb-server-rust/Readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 2c1ad0346..4c7963414 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -8,13 +8,15 @@ _Note:_ This package provides a local DuckDB server. To instead use DuckDB-WASM ## Usage -Install the server with Cargo. +Install the server with Cargo or [Cargo B(inary)Install](https://github.com/cargo-bins/cargo-binstall). ```sh cargo install duckdb-server +# or +cargo binstall duckdb-server ``` -Then run the serve with +Then run the server with ```sh duckdb-server From 4f7c3910c01520b74614b139622dae3024f386b0 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:27:42 -0400 Subject: [PATCH 49/66] ignore data --- packages/duckdb-server-rust/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 34cfdae4b..c93a0e422 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" repository = "https://github.com/uwdata/mosaic" description = "DuckDB Server for Mosaic." license = "BSD 3-Clause" +exclude = [ + "data/*", + ".vscode/*", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 627b113fd9c5b06ecb656d43782feff2ff1bbd68 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:30:24 -0400 Subject: [PATCH 50/66] license --- packages/duckdb-server-rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index c93a0e422..9607dcd1c 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" repository = "https://github.com/uwdata/mosaic" description = "DuckDB Server for Mosaic." -license = "BSD 3-Clause" +license = "BSD-3-Clause" exclude = [ "data/*", ".vscode/*", From 9eed9e5dc495d330b7b01ac8f232d2d7b67414ca Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Mon, 22 Jul 2024 17:37:03 -0400 Subject: [PATCH 51/66] Use ? instead of unwrap in main --- packages/duckdb-server-rust/src/main.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 68ce4cd45..69409a863 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -96,26 +96,25 @@ async fn main() -> Result<(), Box> { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost.pem"), PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost-key.pem"), ) - .await - .unwrap(); + .await?; // Listenfd setup let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 3000); let mut listenfd = ListenFd::from_env(); - let listener = match listenfd.take_tcp_listener(0).unwrap() { + let listener = match listenfd.take_tcp_listener(0)? { // if we are given a tcp listener on listen fd 0, we use that one Some(listener) => { - listener.set_nonblocking(true).unwrap(); + listener.set_nonblocking(true)?; listener } // otherwise fall back to local listening - None => TcpListener::bind(addr).unwrap(), + None => TcpListener::bind(addr)?, }; // Run the server tracing::info!( "DuckDB Server listening on http(s)://{0} and ws://{0}", - listener.local_addr().unwrap() + listener.local_addr()? ); axum_server_dual_protocol::from_tcp_dual_protocol(listener, config) .serve(app.into_make_service()) From 8b69c2a2630d1e31c81b91fb0897429bf07616d7 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 11:15:20 -0400 Subject: [PATCH 52/66] Support also just http --- packages/duckdb-server-rust/Cargo.toml | 2 +- packages/duckdb-server-rust/Readme.md | 14 ++++---- packages/duckdb-server-rust/src/main.rs | 43 +++++++++++++++++++------ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 9607dcd1c..528a10678 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -21,7 +21,7 @@ axum-server = { version = "0.6", features = ["tls-rustls"] } axum-server-dual-protocol = "0.6" duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url", "r2d2"] } futures = "0.3" -listenfd = "1.0.1" +listenfd = "1.0" lru = "0.12" r2d2 = "0.8" regex = "1.5" diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 4c7963414..868ad7935 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -34,6 +34,14 @@ The server can reuse existing sockets with `listenfd`. systemfd --no-pid -s http::3000 -- duckdb-server ``` +To use HTTPS and HTTP/2, you need `localhost.pem` and `localhost-key.pem` in the current directory or at the env variable `CARGO_MANIFEST_DIR`. + +Create certificates for localhost with [mkcert](https://github.com/FiloSottile/mkcert) + +```sh +mkcert localhost +``` + ## Developers ### Build @@ -64,12 +72,6 @@ Or just use (but this won't restart when the code changes) cargo run ``` -Create certificates for HTTPS with - -```sh -mkcert localhost -``` - Before sending a pull request, run the tests with ```sh diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 69409a863..847691787 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -12,6 +12,7 @@ use std::net::TcpListener; use std::sync::Arc; use std::time::Duration; use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; +use tokio::net; use tokio::sync::Mutex; use tower_http::cors::{Any, CorsLayer}; use tower_http::{compression::CompressionLayer, trace::TraceLayer}; @@ -92,11 +93,20 @@ async fn main() -> Result<(), Box> { let app = app()?; // TLS configuration - let config = RustlsConfig::from_pem_file( + let mut config = RustlsConfig::from_pem_file( PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost.pem"), PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("localhost-key.pem"), ) - .await?; + .await; + + if let Err(_) = config { + // try current directory for HTTPS keys if env didn't work + config = RustlsConfig::from_pem_file( + "./localhost.pem", + "./localhost-key.pem", + ) + .await; + } // Listenfd setup let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 3000); @@ -112,13 +122,28 @@ async fn main() -> Result<(), Box> { }; // Run the server - tracing::info!( - "DuckDB Server listening on http(s)://{0} and ws://{0}", - listener.local_addr()? - ); - axum_server_dual_protocol::from_tcp_dual_protocol(listener, config) - .serve(app.into_make_service()) - .await?; + match config { + Err(_) => { + tracing::warn!("No keys for HTTPS found."); + tracing::info!( + "DuckDB Server listening on http://{0} and ws://{0}.", + listener.local_addr()? + ); + + let listener = net::TcpListener::from_std(listener)?; + axum::serve(listener, app).await?; + } + Ok(config) => { + tracing::info!( + "DuckDB Server listening on http(s)://{0} and ws://{0}", + listener.local_addr()? + ); + + axum_server_dual_protocol::from_tcp_dual_protocol(listener, config) + .serve(app.into_make_service()) + .await?; + } + } Ok(()) } From 9435702ac2800b4e208ac42e1c2dc4d7e2df2e70 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 12:04:57 -0400 Subject: [PATCH 53/66] more tests, fix cache key --- packages/duckdb-server-rust/Readme.md | 26 +++++++ packages/duckdb-server-rust/src/cache.rs | 8 ++- packages/duckdb-server-rust/src/interfaces.rs | 1 + packages/duckdb-server-rust/src/main.rs | 8 +-- packages/duckdb-server-rust/src/test.rs | 71 +++++++++++++++++++ 5 files changed, 106 insertions(+), 8 deletions(-) diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 868ad7935..e9d13c6bd 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -42,6 +42,32 @@ Create certificates for localhost with [mkcert](https://github.com/FiloSottile/m mkcert localhost ``` +## API + +The server supports queries via HTTP GET and POST, and WebSockets. The GET endpoint is useful for debugging. For example, you can query it with [this url](). + +Each endpoint takes a JSON object with a command in the `type`. The server supports the following commands. + +### `exec` + +Executes the SQL query in the `sql` field. + +### `arrow` + +Executes the SQL query in the `sql` field and returns the result in Apache Arrow format. + +### `json` + +Executes the SQL query in the `sql` field and returns the result in JSON format. + +### `create-bundle` + +Caches the results of the SQL queries in the `queries` field and the required datasets. + +### `load-bundle` + +Loads the bundled results. + ## Developers ### Build diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index 15a8f9c0d..69eb21aa4 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use serde_json::to_string; +use serde_json::to_value; use tokio::sync::Mutex; use crate::interfaces::Command; @@ -8,7 +8,11 @@ pub fn get_key(sql: &str, command: &Command) -> String { use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); hasher.update(sql); - format!("{:x}.{}", hasher.finalize(), to_string(&command).unwrap()) + format!( + "{:x}.{}", + hasher.finalize(), + to_value(command).unwrap().as_str().unwrap() + ) } pub async fn retrieve( diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 94fb44894..0693ceecd 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -62,6 +62,7 @@ impl IntoResponse for QueryResponse { } } +#[derive(Debug)] pub enum AppError { Error(anyhow::Error), BadRequest, diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 847691787..116faa603 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -99,13 +99,9 @@ async fn main() -> Result<(), Box> { ) .await; - if let Err(_) = config { + if config.is_err() { // try current directory for HTTPS keys if env didn't work - config = RustlsConfig::from_pem_file( - "./localhost.pem", - "./localhost-key.pem", - ) - .await; + config = RustlsConfig::from_pem_file("./localhost.pem", "./localhost-key.pem").await; } // Listenfd setup diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index f5471bbef..0979ff2be 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -9,9 +9,80 @@ use axum::{ http::{self, Request, StatusCode}, }; use http_body_util::BodyExt; +use query::handle; use serde_json::json; use tower::ServiceExt; +use cache::get_key; +use interfaces::Command; + +#[test] +fn key() { + let key = get_key("SELECT 1", &Command::Arrow); + assert_eq!( + key, + "e004ebd5b5532a4b85984a62f8ad48a81aa3460c1ca07701f386135d72cdecf5.arrow" + ); +} + +#[tokio::test] +async fn get_json() -> Result<()> { + let db = ConnectionPool::new(":memory:", 10)?; + let cache = lru::LruCache::new(1000.try_into()?); + + let state = Arc::new(AppState { + db: Box::new(db), + cache: Mutex::new(cache), + }); + + let params = QueryParams { + query_type: Some(Command::Json), + sql: Some("SELECT 1 AS foo".to_string()), + ..QueryParams::default() + }; + + let json = handle(&state, params).await.unwrap(); + + if let QueryResponse::Json(json) = json { + assert_eq!(json, "[{\"foo\":1}]"); + } + + Ok(()) +} + +#[tokio::test] +async fn get_arrow() -> Result<()> { + let db = ConnectionPool::new(":memory:", 10)?; + let cache = lru::LruCache::new(1000.try_into()?); + + let state = Arc::new(AppState { + db: Box::new(db), + cache: Mutex::new(cache), + }); + + let params = QueryParams { + query_type: Some(Command::Arrow), + sql: Some("SELECT 1 AS foo".to_string()), + ..QueryParams::default() + }; + + let arrow = handle(&state, params).await.unwrap(); + + if let QueryResponse::Arrow(arrow) = arrow { + let mut reader = FileReader::try_new(std::io::Cursor::new(arrow), None)?; + let actual_batch = reader.next().unwrap(); + let actual_batch = actual_batch?; + + let schema = Arc::new(Schema::new(vec![Field::new("foo", DataType::Int32, true)])); + let foo_values = Int32Array::from(vec![1]); + let batch = RecordBatch::try_new(schema.clone(), vec![Arc::new(foo_values)])?; + + assert_eq!(actual_batch, batch); + } + + Ok(()) +} + #[tokio::test] async fn select_1_get() -> Result<()> { let app = app()?; From fcb4220c109da5daa6f6fadb26dbadf410c4dbeb Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 12:24:00 -0400 Subject: [PATCH 54/66] test bundling --- packages/duckdb-server-rust/Cargo.lock | 7 ++++ packages/duckdb-server-rust/Cargo.toml | 1 + packages/duckdb-server-rust/src/bundle.rs | 4 +- packages/duckdb-server-rust/src/test.rs | 38 +++++++++++++++++-- .../duckdb-server/pkg/tests/test_bundle.py | 4 ++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 560a96ee5..5a8870841 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -819,6 +819,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "temp_testdir", "tokio", "tower", "tower-http", @@ -2225,6 +2226,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "temp_testdir" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921f1e9c427802414907a48b21a6504ff6b3a15a1a3cf37e699590949ad9befc" + [[package]] name = "thiserror" version = "1.0.63" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 528a10678..1bd678450 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -35,4 +35,5 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } [dev-dependencies] http-body-util = "0.1.0" +temp_testdir = "0.2" tower = { version = "0.4", features = ["util"] } diff --git a/packages/duckdb-server-rust/src/bundle.rs b/packages/duckdb-server-rust/src/bundle.rs index 9b6a51833..37aeea2b2 100644 --- a/packages/duckdb-server-rust/src/bundle.rs +++ b/packages/duckdb-server-rust/src/bundle.rs @@ -16,8 +16,8 @@ pub struct Manifest { #[derive(Serialize, Deserialize, Debug)] pub struct Query { - sql: String, - alias: Option, + pub sql: String, + pub alias: Option, } pub async fn create( diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index 0979ff2be..80a485bfd 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -8,9 +8,11 @@ use axum::{ body::Body, http::{self, Request, StatusCode}, }; +use bundle::{create, load, Query}; use http_body_util::BodyExt; use query::handle; use serde_json::json; +use temp_testdir::TempDir; use tower::ServiceExt; use cache::get_key; @@ -27,8 +29,8 @@ fn key() { #[tokio::test] async fn get_json() -> Result<()> { - let db = ConnectionPool::new(":memory:", 10)?; - let cache = lru::LruCache::new(1000.try_into()?); + let db = ConnectionPool::new(":memory:", 1)?; + let cache = lru::LruCache::new(10.try_into()?); let state = Arc::new(AppState { db: Box::new(db), @@ -52,8 +54,8 @@ async fn get_json() -> Result<()> { #[tokio::test] async fn get_arrow() -> Result<()> { - let db = ConnectionPool::new(":memory:", 10)?; - let cache = lru::LruCache::new(1000.try_into()?); + let db = ConnectionPool::new(":memory:", 1)?; + let cache = lru::LruCache::new(10.try_into()?); let state = Arc::new(AppState { db: Box::new(db), @@ -159,3 +161,31 @@ async fn query_arrow() -> Result<()> { Ok(()) } + + +#[tokio::test] +async fn create_and_load_bundle() -> Result<()> { + let temp = TempDir::default(); + + let db = ConnectionPool::new(":memory:", 1)?; + let cache = &Mutex::new(lru::LruCache::new(10.try_into()?)); + + let queries = vec![ + Query {sql: r#"CREATE TEMP TABLE IF NOT EXISTS flights AS SELECT * FROM read_parquet("data/flights-200k.parquet")"#.to_string(), alias: None}, + Query {sql: r#"SELECT count(*) FROM "flights""#.to_string(), alias: None}, + ]; + + assert_eq!(cache.lock().await.len(), 0); + + create(&db, cache, queries, &temp).await?; + + assert_eq!(cache.lock().await.len(), 1); + cache.lock().await.clear(); + + load(&db, cache, &temp).await?; + + let cache = cache; + assert_eq!(cache.lock().await.len(), 1); + + Ok(()) +} diff --git a/packages/duckdb-server/pkg/tests/test_bundle.py b/packages/duckdb-server/pkg/tests/test_bundle.py index ad43f2014..5b7622218 100644 --- a/packages/duckdb-server/pkg/tests/test_bundle.py +++ b/packages/duckdb-server/pkg/tests/test_bundle.py @@ -21,8 +21,12 @@ def test_bundle(bundle_dir): cache = {} + assert len(cache) == 0 + create_bundle(con, cache, queries, directory=bundle_dir) + assert len(cache) == 0 + load_bundle(con, cache, directory=bundle_dir) assert len(cache) == 1 From 9cc7acd7d711ea5193e6ce712419837f65b23dbf Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 12:33:32 -0400 Subject: [PATCH 55/66] style --- packages/duckdb-server-rust/src/test.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index 80a485bfd..6a9dd8430 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -162,7 +162,6 @@ async fn query_arrow() -> Result<()> { Ok(()) } - #[tokio::test] async fn create_and_load_bundle() -> Result<()> { let temp = TempDir::default(); From 696f5575d067c7468d434745064fc1c8d0f004eb Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 14:51:36 -0400 Subject: [PATCH 56/66] clean up --- packages/duckdb-server-rust/src/websocket.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index ac0bcc008..3acd768ff 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -1,7 +1,4 @@ -use crate::{ - interfaces::{AppError, QueryResponse}, - AppState, -}; +use crate::interfaces::{AppError, AppState, QueryResponse}; use axum::extract::ws::{Message, WebSocket}; use serde_json::json; use std::sync::Arc; From b163348ba7491e1ff21b97841ac942fd86aeccdc Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 16:55:47 -0400 Subject: [PATCH 57/66] bigger pool --- packages/duckdb-server-rust/Cargo.toml | 2 ++ packages/duckdb-server-rust/src/main.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 1bd678450..e658a5c2e 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -37,3 +37,5 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } http-body-util = "0.1.0" temp_testdir = "0.2" tower = { version = "0.4", features = ["util"] } +[profile.release] +codegen-units = 1 diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 116faa603..241d8b163 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -53,7 +53,7 @@ async fn handle_post( pub fn app() -> Result { // Database and state setup - let db = ConnectionPool::new(":memory:", 10)?; + let db = ConnectionPool::new(":memory:", 16)?; let cache = lru::LruCache::new(1000.try_into()?); let state = Arc::new(AppState { From b77d7917f87feb32f69cc5f7dbfe21da7fb7edb9 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 23 Jul 2024 18:16:08 -0400 Subject: [PATCH 58/66] benchmarks --- packages/duckdb-server-rust/Cargo.lock | 254 +++++++++++++++++- packages/duckdb-server-rust/Cargo.toml | 6 + packages/duckdb-server-rust/Readme.md | 6 + .../duckdb-server-rust/benches/benchmark.rs | 43 +++ packages/duckdb-server-rust/src/app.rs | 67 +++++ packages/duckdb-server-rust/src/cache.rs | 1 + packages/duckdb-server-rust/src/interfaces.rs | 2 +- packages/duckdb-server-rust/src/lib.rs | 13 + packages/duckdb-server-rust/src/main.rs | 67 +---- packages/duckdb-server-rust/src/test.rs | 21 +- packages/duckdb-server-rust/src/websocket.rs | 14 +- 11 files changed, 405 insertions(+), 89 deletions(-) create mode 100644 packages/duckdb-server-rust/benches/benchmark.rs create mode 100644 packages/duckdb-server-rust/src/app.rs create mode 100644 packages/duckdb-server-rust/src/lib.rs diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 5a8870841..05e209adc 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -137,7 +137,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half", + "half 2.4.1", "num", ] @@ -152,7 +152,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half", + "half 2.4.1", "hashbrown 0.14.5", "num", ] @@ -164,7 +164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae6970bab043c4fbc10aee1660ceb5b306d0c42c8cc5f6ae564efcd9759b663" dependencies = [ "bytes", - "half", + "half 2.4.1", "num", ] @@ -183,7 +183,7 @@ dependencies = [ "base64 0.22.1", "chrono", "comfy-table", - "half", + "half 2.4.1", "lexical-core", "num", "ryu", @@ -216,7 +216,7 @@ checksum = "a769666ffac256dd301006faca1ca553d0ae7cffcf4cd07095f73f95eb226514" dependencies = [ "arrow-buffer", "arrow-schema", - "half", + "half 2.4.1", "num", ] @@ -246,7 +246,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half", + "half 2.4.1", "indexmap", "lexical-core", "num", @@ -265,7 +265,7 @@ dependencies = [ "arrow-data", "arrow-schema", "arrow-select", - "half", + "half 2.4.1", "num", ] @@ -280,7 +280,7 @@ dependencies = [ "arrow-buffer", "arrow-data", "arrow-schema", - "half", + "half 2.4.1", "hashbrown 0.14.5", ] @@ -366,6 +366,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -669,6 +680,17 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags 1.3.2", + "textwrap", + "unicode-width", +] + [[package]] name = "comfy-table" version = "7.1.1" @@ -724,6 +746,68 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "futures", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crunchy" version = "0.2.2" @@ -809,6 +893,7 @@ dependencies = [ "axum", "axum-server", "axum-server-dual-protocol", + "criterion", "duckdb", "futures", "http-body-util", @@ -827,6 +912,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "equivalent" version = "1.0.1" @@ -1043,6 +1134,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "half" version = "2.4.1" @@ -1094,6 +1191,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1224,6 +1330,15 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1525,7 +1640,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -1544,6 +1659,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + [[package]] name = "overload" version = "0.1.1" @@ -1617,6 +1738,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "plotters" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" + +[[package]] +name = "plotters-svg" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +dependencies = [ + "plotters-backend", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1740,6 +1889,26 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -1949,6 +2118,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scheduled-thread-pool" version = "0.2.7" @@ -1995,6 +2173,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.204" @@ -2232,6 +2420,15 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "921f1e9c427802414907a48b21a6504ff6b3a15a1a3cf37e699590949ad9befc" +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.63" @@ -2271,6 +2468,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2578,6 +2785,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2638,6 +2855,16 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2654,6 +2881,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index e658a5c2e..01251d2fe 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -34,8 +34,14 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [dev-dependencies] +criterion = {version = "0.3", features=["async_futures", "html_reports"]} http-body-util = "0.1.0" temp_testdir = "0.2" tower = { version = "0.4", features = ["util"] } + +[[bench]] +name = "benchmark" +harness = false + [profile.release] codegen-units = 1 diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index e9d13c6bd..5b6e4c820 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -106,6 +106,12 @@ cargo clippy cargo fmt ``` +Run the benchmarks with + +```sh +cargo bench +``` + ### Update dependencies Bump the version in `Cargo.toml` and then run `cargo publish`. diff --git a/packages/duckdb-server-rust/benches/benchmark.rs b/packages/duckdb-server-rust/benches/benchmark.rs new file mode 100644 index 000000000..79769d180 --- /dev/null +++ b/packages/duckdb-server-rust/benches/benchmark.rs @@ -0,0 +1,43 @@ +use criterion::async_executor::FuturesExecutor; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use serde_json::to_value; +use std::sync::Arc; +use tokio::sync::Mutex; + +use duckdb_server::{get_key, handle, AppState, Command, ConnectionPool, QueryParams}; + +pub fn benchmark(c: &mut Criterion) { + let db = ConnectionPool::new(":memory:", 10).unwrap(); + let cache = lru::LruCache::new(10.try_into().unwrap()); + + let state = Arc::new(AppState { + db: Box::new(db), + cache: Mutex::new(cache), + }); + + let mut group = c.benchmark_group("handle"); + for command in [Command::Arrow, Command::Json].iter() { + group.bench_with_input( + BenchmarkId::from_parameter(to_value(command).unwrap().to_string()), + command, + |b, command| { + b.to_async(FuturesExecutor).iter(|| { + let params = QueryParams { + query_type: Some(command.clone()), + sql: Some("SELECT 1 AS foo".to_string()), + ..QueryParams::default() + }; + handle(&state, params) + }) + }, + ); + } + group.finish(); + + c.bench_function("get key", |b| { + b.iter(|| get_key("SELECT 1", &Command::Arrow)) + }); +} + +criterion_group!(benches, benchmark); +criterion_main!(benches); diff --git a/packages/duckdb-server-rust/src/app.rs b/packages/duckdb-server-rust/src/app.rs new file mode 100644 index 000000000..6ed4e3ec7 --- /dev/null +++ b/packages/duckdb-server-rust/src/app.rs @@ -0,0 +1,67 @@ +use anyhow::Result; +use axum::{ + extract::{Query, State, WebSocketUpgrade}, + http::Method, + response::Json, + routing::get, + Router, +}; +use std::sync::Arc; +use std::time::Duration; +use tokio::sync::Mutex; +use tower_http::cors::{Any, CorsLayer}; +use tower_http::{compression::CompressionLayer, trace::TraceLayer}; + +use crate::db::ConnectionPool; +use crate::interfaces::{AppError, AppState, QueryParams, QueryResponse}; +use crate::query; +use crate::websocket; + +async fn handle_get( + State(state): State>, + ws: Option, + Query(params): Query, +) -> Result { + if let Some(ws) = ws { + // WebSocket upgrade + Ok(QueryResponse::Response( + ws.on_upgrade(|socket| websocket::handle(socket, state)), + )) + } else { + // HTTP request + query::handle(&state, params).await + } +} + +async fn handle_post( + State(state): State>, + Json(params): Json, +) -> Result { + query::handle(&state, params).await +} + +pub fn app() -> Result { + // Database and state setup + let db = ConnectionPool::new(":memory:", 16)?; + let cache = lru::LruCache::new(1000.try_into()?); + + let state = Arc::new(AppState { + db: Box::new(db), + cache: Mutex::new(cache), + }); + + // CORS setup + let cors = CorsLayer::new() + .allow_origin(Any) + .allow_methods([Method::OPTIONS, Method::POST, Method::GET]) + .allow_headers(Any) + .max_age(Duration::from_secs(60) * 60 * 24); + + // Router setup + Ok(Router::new() + .route("/", get(handle_get).post(handle_post)) + .with_state(state) + .layer(cors) + .layer(CompressionLayer::new()) + .layer(TraceLayer::new_for_http())) +} diff --git a/packages/duckdb-server-rust/src/cache.rs b/packages/duckdb-server-rust/src/cache.rs index 69eb21aa4..9ebaf804b 100644 --- a/packages/duckdb-server-rust/src/cache.rs +++ b/packages/duckdb-server-rust/src/cache.rs @@ -4,6 +4,7 @@ use tokio::sync::Mutex; use crate::interfaces::Command; +#[must_use] pub fn get_key(sql: &str, command: &Command) -> String { use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 0693ceecd..fb73acec8 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -14,7 +14,7 @@ pub struct AppState { pub cache: Mutex>>, } -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "kebab-case")] pub enum Command { Arrow, diff --git a/packages/duckdb-server-rust/src/lib.rs b/packages/duckdb-server-rust/src/lib.rs new file mode 100644 index 000000000..077b9d92d --- /dev/null +++ b/packages/duckdb-server-rust/src/lib.rs @@ -0,0 +1,13 @@ +mod app; +mod bundle; +mod cache; +mod db; +mod interfaces; +mod query; +mod websocket; + +pub use app::app; +pub use cache::{get_key, retrieve}; +pub use db::{ConnectionPool, Database}; +pub use interfaces::{AppError, AppState, Command, QueryParams, QueryResponse}; +pub use query::handle; diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index 241d8b163..d4926ff6a 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -1,23 +1,12 @@ use anyhow::Result; -use axum::{ - extract::{Query, State, WebSocketUpgrade}, - http::Method, - response::Json, - routing::get, - Router, -}; use axum_server::tls_rustls::RustlsConfig; use listenfd::ListenFd; use std::net::TcpListener; -use std::sync::Arc; -use std::time::Duration; use std::{net::Ipv4Addr, net::SocketAddr, path::PathBuf}; use tokio::net; -use tokio::sync::Mutex; -use tower_http::cors::{Any, CorsLayer}; -use tower_http::{compression::CompressionLayer, trace::TraceLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +mod app; mod bundle; mod cache; mod db; @@ -25,58 +14,6 @@ mod interfaces; mod query; mod websocket; -use db::ConnectionPool; -use interfaces::{AppError, AppState, QueryParams, QueryResponse}; - -async fn handle_get( - State(state): State>, - ws: Option, - Query(params): Query, -) -> Result { - if let Some(ws) = ws { - // WebSocket upgrade - Ok(QueryResponse::Response( - ws.on_upgrade(|socket| websocket::handle(socket, state)), - )) - } else { - // HTTP request - query::handle(&state, params).await - } -} - -async fn handle_post( - State(state): State>, - Json(params): Json, -) -> Result { - query::handle(&state, params).await -} - -pub fn app() -> Result { - // Database and state setup - let db = ConnectionPool::new(":memory:", 16)?; - let cache = lru::LruCache::new(1000.try_into()?); - - let state = Arc::new(AppState { - db: Box::new(db), - cache: Mutex::new(cache), - }); - - // CORS setup - let cors = CorsLayer::new() - .allow_origin(Any) - .allow_methods([Method::OPTIONS, Method::POST, Method::GET]) - .allow_headers(Any) - .max_age(Duration::from_secs(60) * 60 * 24); - - // Router setup - Ok(Router::new() - .route("/", get(handle_get).post(handle_post)) - .with_state(state) - .layer(cors) - .layer(CompressionLayer::new()) - .layer(TraceLayer::new_for_http())) -} - #[tokio::main] async fn main() -> Result<(), Box> { // Tracing setup @@ -90,7 +27,7 @@ async fn main() -> Result<(), Box> { .init(); // App setup - let app = app()?; + let app = app::app()?; // TLS configuration let mut config = RustlsConfig::from_pem_file( diff --git a/packages/duckdb-server-rust/src/test.rs b/packages/duckdb-server-rust/src/test.rs index 6a9dd8430..4cbbb891d 100644 --- a/packages/duckdb-server-rust/src/test.rs +++ b/packages/duckdb-server-rust/src/test.rs @@ -1,4 +1,4 @@ -use super::*; +use anyhow::Result; use arrow::{ array::{Int32Array, RecordBatch}, datatypes::{DataType, Field, Schema}, @@ -8,15 +8,20 @@ use axum::{ body::Body, http::{self, Request, StatusCode}, }; -use bundle::{create, load, Query}; use http_body_util::BodyExt; -use query::handle; use serde_json::json; +use std::sync::Arc; use temp_testdir::TempDir; +use tokio::sync::Mutex; use tower::ServiceExt; -use cache::get_key; -use interfaces::Command; +use crate::bundle::{create, load, Query}; +use crate::cache::get_key; +use crate::db::ConnectionPool; +use crate::interfaces::QueryParams; +use crate::interfaces::QueryResponse; +use crate::interfaces::{AppState, Command}; +use crate::{app, query::handle}; #[test] fn key() { @@ -87,7 +92,7 @@ async fn get_arrow() -> Result<()> { #[tokio::test] async fn select_1_get() -> Result<()> { - let app = app()?; + let app = app::app()?; let response = app .oneshot( @@ -107,7 +112,7 @@ async fn select_1_get() -> Result<()> { #[tokio::test] async fn select_1_post() -> Result<()> { - let app = app()?; + let app = app::app()?; let response = app .oneshot( @@ -131,7 +136,7 @@ async fn select_1_post() -> Result<()> { #[tokio::test] async fn query_arrow() -> Result<()> { - let app = app()?; + let app = app::app()?; let response = app .oneshot( diff --git a/packages/duckdb-server-rust/src/websocket.rs b/packages/duckdb-server-rust/src/websocket.rs index 3acd768ff..ec1306c00 100644 --- a/packages/duckdb-server-rust/src/websocket.rs +++ b/packages/duckdb-server-rust/src/websocket.rs @@ -1,8 +1,15 @@ -use crate::interfaces::{AppError, AppState, QueryResponse}; use axum::extract::ws::{Message, WebSocket}; use serde_json::json; use std::sync::Arc; +use crate::interfaces::{AppError, AppState, QueryResponse}; +use crate::query; + +async fn handle_message(message: String, state: &AppState) -> Result { + let params = serde_json::from_str(&message)?; + query::handle(state, params).await +} + pub async fn handle(mut socket: WebSocket, state: Arc) { while let Some(msg) = socket.recv().await { if let Ok(msg) = msg { @@ -56,8 +63,3 @@ pub async fn handle(mut socket: WebSocket, state: Arc) { } } } - -async fn handle_message(message: String, state: &AppState) -> Result { - let params = serde_json::from_str(&message)?; - crate::query::handle(state, params).await -} From d12f412c6cb2f9a10bb6075a47be4a6f83e5d61f Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 25 Jul 2024 10:46:40 -0400 Subject: [PATCH 59/66] update criterion --- packages/duckdb-server-rust/Cargo.lock | 287 ++++++++++--------------- packages/duckdb-server-rust/Cargo.toml | 2 +- packages/duckdb-server-rust/Readme.md | 4 + 3 files changed, 120 insertions(+), 173 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 05e209adc..60fab065c 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -87,6 +87,18 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + [[package]] name = "anyhow" version = "1.0.86" @@ -137,7 +149,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half 2.4.1", + "half", "num", ] @@ -152,7 +164,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half 2.4.1", + "half", "hashbrown 0.14.5", "num", ] @@ -164,7 +176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae6970bab043c4fbc10aee1660ceb5b306d0c42c8cc5f6ae564efcd9759b663" dependencies = [ "bytes", - "half 2.4.1", + "half", "num", ] @@ -183,7 +195,7 @@ dependencies = [ "base64 0.22.1", "chrono", "comfy-table", - "half 2.4.1", + "half", "lexical-core", "num", "ryu", @@ -216,7 +228,7 @@ checksum = "a769666ffac256dd301006faca1ca553d0ae7cffcf4cd07095f73f95eb226514" dependencies = [ "arrow-buffer", "arrow-schema", - "half 2.4.1", + "half", "num", ] @@ -246,7 +258,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "half 2.4.1", + "half", "indexmap", "lexical-core", "num", @@ -265,7 +277,7 @@ dependencies = [ "arrow-data", "arrow-schema", "arrow-select", - "half 2.4.1", + "half", "num", ] @@ -280,7 +292,7 @@ dependencies = [ "arrow-buffer", "arrow-data", "arrow-schema", - "half 2.4.1", + "half", "hashbrown 0.14.5", ] @@ -366,17 +378,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.3.0" @@ -677,20 +678,61 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.6", + "windows-targets", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", ] [[package]] name = "clap" -version = "2.34.0" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ - "bitflags 1.3.2", - "textwrap", - "unicode-width", + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +dependencies = [ + "anstyle", + "clap_lex", ] +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "comfy-table" version = "7.1.1" @@ -748,25 +790,25 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" dependencies = [ - "atty", + "anes", "cast", + "ciborium", "clap", "criterion-plot", - "csv", "futures", + "is-terminal", "itertools", - "lazy_static", "num-traits", + "once_cell", "oorandom", "plotters", "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -775,9 +817,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", @@ -931,7 +973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -955,7 +997,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -1134,12 +1176,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" - [[package]] name = "half" version = "2.4.1" @@ -1191,15 +1227,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.9" @@ -1330,6 +1357,17 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1347,9 +1385,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -1541,13 +1579,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1634,21 +1673,11 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - [[package]] name = "object" -version = "0.36.1" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -1691,7 +1720,7 @@ dependencies = [ "libc", "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1992,7 +2021,7 @@ dependencies = [ "libc", "spin", "untrusted", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -2065,7 +2094,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -2173,16 +2202,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half 1.8.3", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.204" @@ -2295,7 +2314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -2420,15 +2439,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "921f1e9c427802414907a48b21a6504ff6b3a15a1a3cf37e699590949ad9befc" -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.63" @@ -2495,28 +2505,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.1" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", @@ -2887,7 +2896,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -2902,16 +2911,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -2920,22 +2920,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -2944,46 +2929,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -2996,48 +2963,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 01251d2fe..039bf06e9 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -34,7 +34,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [dev-dependencies] -criterion = {version = "0.3", features=["async_futures", "html_reports"]} +criterion = {version = "0.5", features=["async_futures", "html_reports"]} http-body-util = "0.1.0" temp_testdir = "0.2" tower = { version = "0.4", features = ["util"] } diff --git a/packages/duckdb-server-rust/Readme.md b/packages/duckdb-server-rust/Readme.md index 5b6e4c820..6b87e2db1 100644 --- a/packages/duckdb-server-rust/Readme.md +++ b/packages/duckdb-server-rust/Readme.md @@ -114,4 +114,8 @@ cargo bench ### Update dependencies +Update the lockfile with `cargo update` and look for outdated dependencies with [cargo-outdated](https://github.com/kbknapp/cargo-outdated) `cargo outdated -d 1`. + +### Release + Bump the version in `Cargo.toml` and then run `cargo publish`. From 9d108d77d7cd76e9fec2790b7077774606f75c86 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Sun, 28 Jul 2024 10:31:18 -0400 Subject: [PATCH 60/66] update deps --- packages/duckdb-server-rust/Cargo.lock | 69 +++++++++++++------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 60fab065c..99c9e0777 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -119,9 +119,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "arrow" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6127ea5e585a12ec9f742232442828ebaf264dfa5eefdd71282376c599562b77" +checksum = "05048a8932648b63f21c37d88b552ccc8a65afb6dfe9fc9f30ce79174c2e7a85" dependencies = [ "arrow-arith", "arrow-array", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add7f39210b7d726e2a8efc0083e7bf06e8f2d15bdb4896b564dce4410fbf5d" +checksum = "1d8a57966e43bfe9a3277984a14c24ec617ad874e4c0e1d2a1b083a39cfbf22c" dependencies = [ "arrow-array", "arrow-buffer", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81c16ec702d3898c2f5cfdc148443c6cd7dbe5bac28399859eb0a3d38f072827" +checksum = "16f4a9468c882dc66862cef4e1fd8423d47e67972377d85d80e022786427768c" dependencies = [ "ahash 0.8.11", "arrow-buffer", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae6970bab043c4fbc10aee1660ceb5b306d0c42c8cc5f6ae564efcd9759b663" +checksum = "c975484888fc95ec4a632cdc98be39c085b1bb518531b0c80c5d462063e5daa1" dependencies = [ "bytes", "half", @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7ef44f26ef4f8edc392a048324ed5d757ad09135eff6d5509e6450d39e0398" +checksum = "da26719e76b81d8bc3faad1d4dbdc1bcc10d14704e63dc17fc9f3e7e1e567c8e" dependencies = [ "arrow-array", "arrow-buffer", @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "arrow-csv" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f843490bd258c5182b66e888161bb6f198f49f3792f7c7f98198b924ae0f564" +checksum = "c13c36dc5ddf8c128df19bab27898eea64bf9da2b555ec1cd17a8ff57fba9ec2" dependencies = [ "arrow-array", "arrow-buffer", @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a769666ffac256dd301006faca1ca553d0ae7cffcf4cd07095f73f95eb226514" +checksum = "dd9d6f18c65ef7a2573ab498c374d8ae364b4a4edf67105357491c031f716ca5" dependencies = [ "arrow-buffer", "arrow-schema", @@ -234,9 +234,9 @@ dependencies = [ [[package]] name = "arrow-ipc" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf9c3fb57390a1af0b7bb3b5558c1ee1f63905f3eccf49ae7676a8d1e6e5a72" +checksum = "e786e1cdd952205d9a8afc69397b317cfbb6e0095e445c69cda7e8da5c1eeb0f" dependencies = [ "arrow-array", "arrow-buffer", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "arrow-json" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "654e7f3724176b66ddfacba31af397c48e106fbe4d281c8144e7d237df5acfd7" +checksum = "fb22284c5a2a01d73cebfd88a33511a3234ab45d66086b2ca2d1228c3498e445" dependencies = [ "arrow-array", "arrow-buffer", @@ -268,9 +268,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8008370e624e8e3c68174faaf793540287106cfda8ad1da862fdc53d8e096b4" +checksum = "42745f86b1ab99ef96d1c0bcf49180848a64fe2c7a7a0d945bc64fa2b21ba9bc" dependencies = [ "arrow-array", "arrow-buffer", @@ -283,9 +283,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5e3a6b7fda8d9fe03f3b18a2d946354ea7f3c8e4076dbdb502ad50d9d44824" +checksum = "4cd09a518c602a55bd406bcc291a967b284cfa7a63edfbf8b897ea4748aad23c" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -293,23 +293,22 @@ dependencies = [ "arrow-data", "arrow-schema", "half", - "hashbrown 0.14.5", ] [[package]] name = "arrow-schema" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab1c12b40e29d9f3b699e0203c2a73ba558444c05e388a4377208f8f9c97eee" +checksum = "9e972cd1ff4a4ccd22f86d3e53e835c2ed92e0eea6a3e8eadb72b4f1ac802cf8" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "arrow-select" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e80159088ffe8c48965cb9b1a7c968b2729f29f37363df7eca177fc3281fe7c3" +checksum = "600bae05d43483d216fb3494f8c32fdbefd8aa4e1de237e790dbb3d9f44690a3" dependencies = [ "ahash 0.8.11", "arrow-array", @@ -321,9 +320,9 @@ dependencies = [ [[package]] name = "arrow-string" -version = "52.1.0" +version = "52.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fd04a6ea7de183648edbcb7a6dd925bbd04c210895f6384c780e27a9b54afcd" +checksum = "f0dc1985b67cb45f6606a248ac2b4a288849f196bab8c657ea5589f47cdd55e6" dependencies = [ "arrow-array", "arrow-buffer", @@ -2505,9 +2504,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", @@ -2569,9 +2568,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" [[package]] name = "toml_edit" @@ -2790,9 +2789,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" From 20d76fb692df600b217d9b9724cd037bfb01b7cb Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 2 Aug 2024 12:42:00 -0400 Subject: [PATCH 61/66] chore: update deps --- packages/duckdb-server-rust/Cargo.lock | 77 +++++++++++++++++--------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 99c9e0777..74dfd6918 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -39,7 +39,7 @@ dependencies = [ "getrandom", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -636,9 +636,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cast" @@ -648,9 +648,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -709,18 +709,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstyle", "clap_lex", @@ -1348,9 +1348,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1533,9 +1533,9 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" dependencies = [ "hashbrown 0.14.5", ] @@ -1796,9 +1796,12 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy 0.6.6", +] [[package]] name = "proc-macro-crate" @@ -1957,9 +1960,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -2214,11 +2217,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2568,9 +2572,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -3015,13 +3019,34 @@ dependencies = [ "rustix", ] +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.6", +] + [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] @@ -3046,18 +3071,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.12+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", From 5307edfbf06dd4bf476fb9e4a680f501df1cc95d Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 13 Aug 2024 17:58:26 -0700 Subject: [PATCH 62/66] update deps --- packages/duckdb-server-rust/Cargo.lock | 494 ++++++++++++++++++------- packages/duckdb-server-rust/Cargo.toml | 6 +- 2 files changed, 361 insertions(+), 139 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 74dfd6918..1285b1b13 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -39,7 +39,7 @@ dependencies = [ "getrandom", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -359,7 +359,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -383,6 +383,33 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "aws-lc-rs" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae74d9bd0a7530e8afd1770739ad34b36838829d6ad61818f9230f683f5ad77" +dependencies = [ + "aws-lc-sys", + "mirai-annotations", + "paste", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0e249228c6ad2d240c2dc94b714d711629d52bad946075d8e9b2f5391f0703" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "axum" version = "0.7.5" @@ -415,7 +442,7 @@ dependencies = [ "sync_wrapper 1.0.1", "tokio", "tokio-tungstenite", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -451,14 +478,14 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] name = "axum-server" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad46c3ec4e12f4a4b6835e173ba21c25e484c9d02b49770bf006ce5367c036" +checksum = "56bac90848f6a9393ac03c63c640925c4b7c8ca21654de40d53f55964667c7d8" dependencies = [ "arc-swap", "bytes", @@ -471,23 +498,25 @@ dependencies = [ "pin-project-lite", "rustls", "rustls-pemfile", + "rustls-pki-types", "tokio", "tokio-rustls", - "tower", + "tower 0.4.13", "tower-service", ] [[package]] name = "axum-server-dual-protocol" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea4cd08ae2a5f075d28fa31190163c8106a1d2d3189442494bae22b39040a0d" +checksum = "2164551db024e87f20316d164eab9f5ad342d8188b08051ceb15ca92a60ea7b7" dependencies = [ "axum-server", "bytes", "http", "http-body-util", "pin-project", + "rustls", "tokio", "tokio-rustls", "tokio-util", @@ -522,6 +551,29 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.74", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -575,7 +627,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", "syn_derive", ] @@ -648,14 +700,23 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" dependencies = [ "jobserver", "libc", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -707,20 +768,31 @@ dependencies = [ "half", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.13" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstyle", "clap_lex", @@ -732,6 +804,15 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + [[package]] name = "comfy-table" version = "7.1.1" @@ -765,15 +846,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -800,7 +881,7 @@ dependencies = [ "criterion-plot", "futures", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -821,7 +902,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -947,12 +1028,18 @@ dependencies = [ "sha2", "temp_testdir", "tokio", - "tower", + "tower 0.5.0", "tower-http", "tracing", "tracing-subscriber", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.13.0" @@ -972,7 +1059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -989,14 +1076,14 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -1011,9 +1098,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -1034,6 +1121,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "funty" version = "2.0.0" @@ -1096,7 +1189,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -1156,6 +1249,12 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.4.5" @@ -1232,6 +1331,15 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "1.1.0" @@ -1300,9 +1408,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ "bytes", "futures-util", @@ -1348,9 +1456,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1364,7 +1472,7 @@ checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1376,6 +1484,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1393,9 +1510,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -1406,6 +1523,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "lexical-core" version = "0.8.5" @@ -1492,12 +1615,33 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + [[package]] name = "libm" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1567,6 +1711,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1578,14 +1728,30 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "mirai-annotations" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", ] [[package]] @@ -1674,9 +1840,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -1717,11 +1883,17 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1745,7 +1917,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -1796,11 +1968,21 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy 0.6.6", + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.74", ] [[package]] @@ -1940,15 +2122,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -2023,7 +2196,7 @@ dependencies = [ "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2077,6 +2250,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -2096,26 +2275,28 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ - "log", - "ring", + "aws-lc-rs", + "once_cell", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -2123,17 +2304,19 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ + "aws-lc-rs", "ring", + "rustls-pki-types", "untrusted", ] @@ -2173,16 +2356,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "seahash" version = "4.1.0" @@ -2197,29 +2370,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", "memchr", @@ -2280,6 +2453,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -2317,7 +2496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2357,7 +2536,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -2370,9 +2549,15 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.74", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -2386,9 +2571,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", @@ -2404,7 +2589,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -2459,7 +2644,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -2521,7 +2706,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2532,16 +2717,17 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", + "rustls-pki-types", "tokio", ] @@ -2603,6 +2789,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36b837f86b25d7c0d7988f00a54e74739be6477f2aac6201b8f429a7569991b7" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-http" version = "0.5.2" @@ -2626,15 +2826,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -2656,7 +2856,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -2815,34 +3015,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2850,33 +3051,45 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2895,11 +3108,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -2926,6 +3139,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -3021,43 +3243,43 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.6.6" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive 0.6.6", + "zerocopy-derive", ] [[package]] -name = "zerocopy" +name = "zerocopy-derive" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "zerocopy-derive 0.7.35", + "proc-macro2", + "quote", + "syn 2.0.74", ] [[package]] -name = "zerocopy-derive" -version = "0.6.6" +name = "zeroize" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", + "zeroize_derive", ] [[package]] -name = "zerocopy-derive" -version = "0.7.35" +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index 039bf06e9..3edfbcaeb 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -17,8 +17,8 @@ anyhow = "1.0" arrow = "52.1" async-trait = "0.1.80" axum = { version = "0.7", features = ["http1", "http2", "ws", "json", "tokio", "tracing", "macros"] } -axum-server = { version = "0.6", features = ["tls-rustls"] } -axum-server-dual-protocol = "0.6" +axum-server = { version = "0.7", features = ["tls-rustls"] } +axum-server-dual-protocol = "0.7" duckdb = { version = "1", features = ["bundled", "csv", "json", "parquet", "url", "r2d2"] } futures = "0.3" listenfd = "1.0" @@ -37,7 +37,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } criterion = {version = "0.5", features=["async_futures", "html_reports"]} http-body-util = "0.1.0" temp_testdir = "0.2" -tower = { version = "0.4", features = ["util"] } +tower = { version = "0.5", features = ["util"] } [[bench]] name = "benchmark" From dd086f563b7958bbe441aadb77dd3d0253b8d1c1 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Tue, 13 Aug 2024 23:13:25 -0700 Subject: [PATCH 63/66] clean up --- packages/duckdb-server-rust/src/db.rs | 3 +-- packages/duckdb-server-rust/src/main.rs | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index c3b7f78d0..aee53d695 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -44,8 +44,7 @@ impl Database for ConnectionPool { writer.write(&batch)?; } writer.finish()?; - let json_data = writer.into_inner(); - Ok(json_data) + Ok(writer.into_inner()) } async fn get_arrow(&self, sql: &str) -> Result> { diff --git a/packages/duckdb-server-rust/src/main.rs b/packages/duckdb-server-rust/src/main.rs index d4926ff6a..87fdfe219 100644 --- a/packages/duckdb-server-rust/src/main.rs +++ b/packages/duckdb-server-rust/src/main.rs @@ -80,6 +80,3 @@ async fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(test)] -mod test; From ffc034a8891a324e18a71773bd9f7312be100c7b Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Wed, 14 Aug 2024 12:05:22 -0400 Subject: [PATCH 64/66] Stream Arrow RecordBatches using mpsc channel and tokio_streams (#481) --- packages/duckdb-server-rust/Cargo.lock | 1 + packages/duckdb-server-rust/Cargo.toml | 1 + packages/duckdb-server-rust/src/db.rs | 95 +++++++------------------- 3 files changed, 27 insertions(+), 70 deletions(-) diff --git a/packages/duckdb-server-rust/Cargo.lock b/packages/duckdb-server-rust/Cargo.lock index 759d5a97e..ab1dcc9b3 100644 --- a/packages/duckdb-server-rust/Cargo.lock +++ b/packages/duckdb-server-rust/Cargo.lock @@ -899,6 +899,7 @@ dependencies = [ "serde_json", "sha2", "tokio", + "tokio-stream", "tower", "tower-http", "tracing", diff --git a/packages/duckdb-server-rust/Cargo.toml b/packages/duckdb-server-rust/Cargo.toml index ce0a7b6c1..fbd4a654c 100644 --- a/packages/duckdb-server-rust/Cargo.toml +++ b/packages/duckdb-server-rust/Cargo.toml @@ -29,6 +29,7 @@ axum-streams = { version = "0.18", features=["arrow"] } async-stream = "0.3" deadpool = { version = "0.12", features = ["managed"] } deadpool-r2d2 = {version = "0.4.1"} +tokio-stream = "0.1" [dev-dependencies] http-body-util = "0.1.0" diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index 2f8f77c65..5eb0885e8 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -17,6 +17,9 @@ use tracing::span::Record; use futures::future::FutureExt; use futures::stream::StreamExt; +use tokio::sync::mpsc; +use tokio_stream::wrappers::ReceiverStream; + use crate::interfaces::adapt_anyhow_error; #[async_trait] @@ -24,11 +27,10 @@ pub trait Database: Send + Sync { async fn execute(&self, sql: String) -> Result<()>; async fn get_json(&self, sql: String) -> Result>; async fn get_arrow(&self, sql: String) -> Result>; - // async fn stream_arrow(&self, sql: String) -> Result; async fn stream_record_batch( &self, sql: String, - ) -> impl Stream;// Result>>; + ) -> Result>, Error>; } type DuckDBManager = deadpool_r2d2::Manager; @@ -108,79 +110,32 @@ impl Database for ConnectionPool { Ok(buffer) } - // async fn stream_arrow(&self, sql: String) -> Result { - // let conn = self.pool.get().await?; - // let stream = conn.interact(move |client| { - // let mut stmt = client.prepare(&sql)?; - // let arrow = stmt.query_arrow([])?; - // let schema = arrow.get_schema(); - - // let stream = async_stream::try_stream! { - // for batch in arrow { - // yield batch; - // } - // }; - // Ok(StreamBodyAs::arrow_ipc_with_errors(schema, stream)) - // }).await.map_err(adapt_anyhow_error)??; - - // let response = stream.into_response(); - // Ok(response) - // } - async fn stream_record_batch( &self, sql: String, - ) -> Result>> { + ) -> Result>, Error> { let conn = self.pool.get().await?; - - let stream = std::pin::pin! { conn - .interact(move |conn| { + let (tx, rx) = mpsc::channel(100); + + tokio::spawn(async move { + let result = conn.interact(move |conn| { let mut stmt = conn.prepare(&sql)?; let arrow = stmt.query_arrow([])?; - let schema = arrow.get_schema(); - - let stream = stream! { - for batch in arrow { - yield batch; + + for batch in arrow { + if let Err(e) = tx.blocking_send(batch) { + tracing::error!("Error processing batch: {:?}", e); + break; } - }; - - Ok(stream) - }) - .await - .map_err(adapt_anyhow_error)?? }; - - Ok(stream) - } - - // fn stream_record_batch(&self, sql: &str) -> impl Stream> { - // let pool = self.pool.clone(); - // async_stream::try_stream! { - // let conn = pool.get()?; - // let mut stmt = conn.prepare(sql)?; - // let arrow = stmt.query_arrow([])?; - - // for batch in arrow { - // yield batch; - // } - // } - // } - - // fn stream_record_batch( - // &self, - // sql: &str, - // ) -> Pin> + Send>> { - // let pool = self.pool.clone(); - // Box::pin(futures::stream::unfold( - // (pool, sql.to_string()), - // |(pool, sql)| async move { - // let conn = pool.get().ok()?; - // let mut stmt = conn.prepare(&sql).ok()?; - // let mut arrow = stmt.query_arrow([]).ok()?; - - // let batch = arrow.next()?; - // Some((Ok(batch), (pool, sql))) - // }, - // )) - // } + } + Ok::<_, Error>(()) + }).await; + + if let Err(e) = result { + tracing::error!("Error in database interaction: {:?}", e); + } + }); + + Ok(Box::new(ReceiverStream::new(rx))) + } } From f23763c4fa90e0af2c1567a64796eb2a2931bbeb Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Wed, 14 Aug 2024 09:37:24 -0700 Subject: [PATCH 65/66] clean up --- packages/duckdb-server-rust/src/db.rs | 39 ++++++++++-------- packages/duckdb-server-rust/src/interfaces.rs | 41 ------------------- 2 files changed, 21 insertions(+), 59 deletions(-) diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index 5eb0885e8..5b9c7251a 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,7 +1,7 @@ use anyhow::{Error, Result}; use arrow::record_batch::RecordBatch; -use async_stream::try_stream; use async_stream::stream; +use async_stream::try_stream; use async_trait::async_trait; use axum::response::IntoResponse; use axum_streams::StreamBodyAs; @@ -9,13 +9,13 @@ use deadpool::managed::{Manager, Object, Pool}; use deadpool_r2d2::Runtime; use duckdb::arrow::ipc::writer::StreamWriter; use duckdb::DuckdbConnectionManager; +use futures::future::FutureExt; use futures::prelude::*; use futures::stream::BoxStream; use futures::stream::Stream; +use futures::stream::StreamExt; use std::{pin::Pin, sync::Arc}; use tracing::span::Record; -use futures::future::FutureExt; -use futures::stream::StreamExt; use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; @@ -54,7 +54,8 @@ impl ConnectionPool { impl Database for ConnectionPool { async fn execute(&self, sql: String) -> Result<()> { let manager = self.pool.get().await?; - manager.interact(move |conn| conn.execute_batch(&sql)) + manager + .interact(move |conn| conn.execute_batch(&sql)) .await .map_err(adapt_anyhow_error)?; Ok(()) @@ -116,26 +117,28 @@ impl Database for ConnectionPool { ) -> Result>, Error> { let conn = self.pool.get().await?; let (tx, rx) = mpsc::channel(100); - + tokio::spawn(async move { - let result = conn.interact(move |conn| { - let mut stmt = conn.prepare(&sql)?; - let arrow = stmt.query_arrow([])?; - - for batch in arrow { - if let Err(e) = tx.blocking_send(batch) { - tracing::error!("Error processing batch: {:?}", e); - break; + let result = conn + .interact(move |conn| { + let mut stmt = conn.prepare(&sql)?; + let arrow = stmt.query_arrow([])?; + + for batch in arrow { + if let Err(e) = tx.blocking_send(batch) { + tracing::error!("Error processing batch: {:?}", e); + break; + } } - } - Ok::<_, Error>(()) - }).await; - + Ok::<_, Error>(()) + }) + .await; + if let Err(e) = result { tracing::error!("Error in database interaction: {:?}", e); } }); - + Ok(Box::new(ReceiverStream::new(rx))) } } diff --git a/packages/duckdb-server-rust/src/interfaces.rs b/packages/duckdb-server-rust/src/interfaces.rs index 633dc0409..e4d16497a 100644 --- a/packages/duckdb-server-rust/src/interfaces.rs +++ b/packages/duckdb-server-rust/src/interfaces.rs @@ -110,44 +110,3 @@ impl Error for InteractError { anyhow!("Interact Error {:?}", self) } } - - -// pub fn adapt_app_error(error: T) -> AppError { -// error.as_app_error() -// } - -// pub trait Error { -// fn as_app_error(&self) -> AppError; -// } - -// impl Error for InteractError { -// fn as_app_error(&self) -> AppError { -// AppError::InteractError -// } -// } - -// #[derive(Debug)] -// pub struct InfraError; - -// pub fn adapt_infra_error(error: T) -> InfraError { -// error.as_infra_error() -// } - -// pub trait Error { -// fn as_infra_error(&self) -> InfraError; -// } - -// impl Error for InteractError { -// fn as_infra_error(&self) -> InfraError { -// InfraError -// } -// } - -// impl From for InfraError -// where -// E: Into, -// { -// fn from(_: E) -> Self { -// InfraError -// } -// } From 711f0c3ffd658b8f1425aa88e1e4f8c430169935 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Wed, 14 Aug 2024 09:42:57 -0700 Subject: [PATCH 66/66] fix warnings --- packages/duckdb-server-rust/src/db.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/duckdb-server-rust/src/db.rs b/packages/duckdb-server-rust/src/db.rs index 5b9c7251a..3a861f0f9 100644 --- a/packages/duckdb-server-rust/src/db.rs +++ b/packages/duckdb-server-rust/src/db.rs @@ -1,21 +1,9 @@ use anyhow::{Error, Result}; use arrow::record_batch::RecordBatch; -use async_stream::stream; -use async_stream::try_stream; use async_trait::async_trait; -use axum::response::IntoResponse; -use axum_streams::StreamBodyAs; -use deadpool::managed::{Manager, Object, Pool}; use deadpool_r2d2::Runtime; -use duckdb::arrow::ipc::writer::StreamWriter; use duckdb::DuckdbConnectionManager; -use futures::future::FutureExt; -use futures::prelude::*; -use futures::stream::BoxStream; use futures::stream::Stream; -use futures::stream::StreamExt; -use std::{pin::Pin, sync::Arc}; -use tracing::span::Record; use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; @@ -54,7 +42,7 @@ impl ConnectionPool { impl Database for ConnectionPool { async fn execute(&self, sql: String) -> Result<()> { let manager = self.pool.get().await?; - manager + let _ = manager .interact(move |conn| conn.execute_batch(&sql)) .await .map_err(adapt_anyhow_error)?;